Re: [PATCH v2 4/5] block, scsi: Rework runtime power management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 07/27/2018 11:29 PM, Bart Van Assche wrote:
> On Fri, 2018-07-27 at 09:57 +0800, jianchao.wang wrote:
>> Something like:
>>
>> 	percpu_ref_switch_to_atomic_sync(&q->q_usage_counter);
>> 	if (!percpu_ref_is_zero(&q->q_usage_counter)) {
>> 		ret = -EBUSY;
>> 		pm_runtime_mark_last_busy(q->dev);
>>      	} else {
>> 		blk_set_preempt_only(q);
>> 		if (!percpu_ref_is_zero(&q->q_usage_counter) {
>> 			ret = -EBUSY;
>> 			pm_runtime_mark_last_busy(q->dev);
>> 			blk_clear_preempt_only(q);
>> 		} else {
>> 			q->rpm_status = RPM_SUSPENDIN;    
>> 		}
>>         }
> 
> I think this code is racy. Because there is no memory barrier in
> blk_queue_enter() between the percpu_ref_tryget_live() and the
> blk_queue_preempt_only() calls, the context that sets the PREEMPT_ONLY flag
> has to use synchronize_rcu() or call_rcu() to ensure that blk_queue_enter()
> sees the PREEMPT_ONLY flag after it has called percpu_ref_tryget_live().
> See also https://urldefense.proofpoint.com/v2/url?u=http-3A__lwn.net_Articles_573497_&d=DwIFgQ&c=RoP1YumCXCgaWHvlZYR8PZh8Bv7qIrMUB65eapI_JnE&r=7WdAxUBeiTUTCy8v-7zXyr4qk7sx26ATvfo6QSTvZyQ&m=mkAOXQtxuVTAej2tBjOvEed2h4TRvX3mE-EPeNEUD5E&s=xTgTB2x1JwvRUQVyOL8m3rhbbk8xhOkZMC_Io9bmpFc&e=.

Yes, a synchrorize_rcu is indeed needed here to ensure a q_usage_counter is
got successfully with increasing one,  or unsuccessfully without increasing one.

Thanks
Jianchao



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux