/* * Waiting for a read lock or a write lock on a rwlock... * This turns out to be the same for read and write locks, since * we only know the holder if it is write-locked. */ void __rw_yield(raw_rwlock_t *rw) { int lock_value; unsigned int holder_cpu, yield_count; lock_value = rw->lock; if (lock_value >= 0) return; /* no write lock at present */ holder_cpu = lock_value & 0xffff; BUG_ON(holder_cpu >= NR_CPUS); yield_count = lppaca[holder_cpu].yield_count; if ((yield_count & 1) == 0) return; /* virtual cpu is currently running */ rmb(); if (rw->lock != lock_value) return; /* something has changed */ if (firmware_has_feature(FW_FEATURE_ISERIES)) HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, ((u64)holder_cpu << 32) | yield_count); #ifdef CONFIG_PPC_SPLPAR else plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), yield_count); #endif }
/*===================================================================== */ void HvCall_writeLogBuffer(const void *buffer, u64 bufLen) { struct HvLpBufferList bufList; u64 bytesLeft = bufLen; u64 leftThisPage; u64 curPtr = virt_to_absolute((unsigned long) buffer); while (bytesLeft) { bufList.addr = curPtr; leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr; if (leftThisPage > bytesLeft) { bufList.len = bytesLeft; bytesLeft = 0; } else { bufList.len = leftThisPage; bytesLeft -= leftThisPage; } HvCall2(HvCallBaseWriteLogBuffer, virt_to_absolute((unsigned long) &bufList), bufList.len); curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; } }
void __spin_yield(raw_spinlock_t *lock) { unsigned int lock_value, holder_cpu, yield_count; struct paca_struct *holder_paca; lock_value = lock->slock; if (lock_value == 0) return; holder_cpu = lock_value & 0xffff; BUG_ON(holder_cpu >= NR_CPUS); holder_paca = &paca[holder_cpu]; yield_count = holder_paca->lppaca.yield_count; if ((yield_count & 1) == 0) return; /* virtual cpu is currently running */ rmb(); if (lock->slock != lock_value) return; /* something has changed */ #ifdef CONFIG_PPC_ISERIES HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, ((u64)holder_cpu << 32) | yield_count); #else plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), yield_count); #endif }
void __spin_yield(__raw_spinlock_t *lock) { unsigned int lock_value, holder_cpu, yield_count; lock_value = lock->slock; if (lock_value == 0) return; holder_cpu = lock_value & 0xffff; BUG_ON(holder_cpu >= NR_CPUS); yield_count = lppaca[holder_cpu].yield_count; if ((yield_count & 1) == 0) return; /* virtual cpu is currently running */ rmb(); if (lock->slock != lock_value) return; /* something has changed */ if (firmware_has_feature(FW_FEATURE_ISERIES)) HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, ((u64)holder_cpu << 32) | yield_count); else plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), yield_count); }