Re: [PATCH v4 07/28] block: Introduce zone write plugging

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

 



On 4/3/24 10:01, Jens Axboe wrote:
> On 4/2/24 5:38 PM, Damien Le Moal wrote:
>> On 4/3/24 01:12, Christoph Hellwig wrote:
>>>> +static inline struct blk_zone_wplug *
>>>> +disk_lookup_zone_wplug(struct gendisk *disk, sector_t sector)
>>>> +{
>>>> +	unsigned int zno = disk_zone_no(disk, sector);
>>>> +	unsigned int idx = hash_32(zno, disk->zone_wplugs_hash_bits);
>>>> +	struct blk_zone_wplug *zwplug;
>>>> +
>>>> +	rcu_read_lock();
>>>> +	hlist_for_each_entry_rcu(zwplug, &disk->zone_wplugs_hash[idx], node) {
>>>> +		if (zwplug->zone_no == zno)
>>>> +			goto unlock;
>>>> +	}
>>>> +	zwplug = NULL;
>>>> +
>>>> +unlock:
>>>> +	rcu_read_unlock();
>>>> +	return zwplug;
>>>> +}
>>>
>>> Did we lose an atomic_inc_unless_zero here?  This now just does a lookup
>>> under RCU, but nothing to prevent the zwplug from beeing freed?
>>
>> Nope. When disk_lookup_zone_wplug() is called directly, it is always
>> for handling requests/bios which are holding a reference on the plug
>> and because there are requests/BIOs in-flight, the plug is marked as
>> busy (BLK_ZONE_WPLUG_PLUGGED or BLK_ZONE_WPLUG_ERROR are set). In such
>> state, the plug is always hashed given that
>> disk_should_remove_zone_wplug() retturns false for busy plugs. So
>> there is no reference increase here. The atomic_inc_not_zero() is in
>> disk_get_zone_wplug() which calls disk_lookup_zone_wplug() +
>> atomic_inc_not_zero() within an rcu_read_lock()/rcu_read_unlock()
>> section.
> 
> But doing a lookup under rcu, dropping it, and then returning the unit
> without an increment is just a horrible pattern. Regardless of whether
> it's safe or not. And as most callers do the atomic_inc anyway, some of
> then outside rcu lock, this looks horrible buggy.
> 
> Please just unify it all and have it follow the idiomatic rcu lookup
> pattern, which is:
> 
> rcu_read_lock();
> item = lookup();
> if (atomic_inc_not_zero(item->ref)) {
> 	rcu_read_unlock();
> 	return item;
> }
> 
> rcu_read_unlock();
> return NULL;
> 
> as that is well understood, and your code most certainly does not look
> safe nor sane in that regard.
> 
> And probably kill that atomic_inc() helper you have as well while at it.

OK.

> 

-- 
Damien Le Moal
Western Digital Research





[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux