Message ID | 20250109055810.1402918-7-hch@lst.de |
---|---|
State | New |
Headers | show |
Series | [01/11] block: fix docs for freezing of queue limits updates | expand |
On Thu, Jan 09, 2025 at 01:07:47PM +0000, John Garry wrote: > Do you mean that the sysfs_lock could be removed in future? I would have > thought that queue limits lock could be used for the same thing, but I am > probably failing to see some lock nesting/ordering issues... More or less. Think about it: what does it even try to protect? Readіng/writing sysfs files vs itself and file removal it serialized by sysfs/kernfs internally. Any information tweaked in sysfs usually also has other places that can modify it. So we'll need a lock independent of sysfs for that anyway. A big part, buy by far all of that is covered by limits_lock. Serializing creating/removing sysfs attribues is supposed to be serialized using sysfs_dir_lock, although that needs a careful audit. It's also used to serialize a few debugfs things, but we'll need to look carefully for what exactly and switch that over to debugfs_mutex or something new. And then there's a bunch of misc cruft that also needs a careful look.
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index d2aa2177e4ba..e828be777206 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -694,22 +694,24 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr, if (entry->load_module) entry->load_module(disk, page, length); - mutex_lock(&q->sysfs_lock); - blk_mq_freeze_queue(q); if (entry->store_limit) { struct queue_limits lim = queue_limits_start_update(q); res = entry->store_limit(disk, page, length, &lim); if (res < 0) { queue_limits_cancel_update(q); - } else { - res = queue_limits_commit_update(q, &lim); - if (!res) - res = length; + return res; } - } else { - res = entry->store(disk, page, length); + + res = queue_limits_commit_update_frozen(q, &lim); + if (res) + return res; + return length; } + + mutex_lock(&q->sysfs_lock); + blk_mq_freeze_queue(q); + res = entry->store(disk, page, length); blk_mq_unfreeze_queue(q); mutex_unlock(&q->sysfs_lock); return res;