Skip to content

Commit 4396943

Browse files
author
Ming Lei
committed
block: add a store_limit operations for sysfs entries
JIRA: https://issues.redhat.com/browse/RHEL-71345 Conflicts: We don't backport "110234da18ab block: enable passthrough command statistics" Upstream Status: for-6.4/block commit a162306 Author: Christoph Hellwig <hch@lst.de> Date: Fri Jan 10 06:47:13 2025 +0100 block: add a store_limit operations for sysfs entries De-duplicate the code for updating queue limits by adding a store_limit method that allows having common code handle the actual queue limits update. Note that this is a pure refactoring patch and does not address the existing freeze vs limits lock order problem in the refactored code, which will be addressed next. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Nilay Shroff <nilay@linux.ibm.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: John Garry <john.g.garry@oracle.com> Link: https://lore.kernel.org/r/20250110054726.1499538-6-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Ming Lei <ming.lei@redhat.com>
1 parent 27ec0bf commit 4396943

File tree

1 file changed

+54
-54
lines changed

1 file changed

+54
-54
lines changed

block/blk-sysfs.c

Lines changed: 54 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ struct queue_sysfs_entry {
2424
struct attribute attr;
2525
ssize_t (*show)(struct gendisk *disk, char *page);
2626
ssize_t (*store)(struct gendisk *disk, const char *page, size_t count);
27+
int (*store_limit)(struct gendisk *disk, const char *page,
28+
size_t count, struct queue_limits *lim);
2729
void (*load_module)(struct gendisk *disk, const char *page, size_t count);
2830
};
2931

@@ -152,13 +154,11 @@ QUEUE_SYSFS_SHOW_CONST(discard_zeroes_data, 0)
152154
QUEUE_SYSFS_SHOW_CONST(write_same_max, 0)
153155
QUEUE_SYSFS_SHOW_CONST(poll_delay, -1)
154156

155-
static ssize_t queue_max_discard_sectors_store(struct gendisk *disk,
156-
const char *page, size_t count)
157+
static int queue_max_discard_sectors_store(struct gendisk *disk,
158+
const char *page, size_t count, struct queue_limits *lim)
157159
{
158160
unsigned long max_discard_bytes;
159-
struct queue_limits lim;
160161
ssize_t ret;
161-
int err;
162162

163163
ret = queue_var_store(&max_discard_bytes, page, count);
164164
if (ret < 0)
@@ -170,12 +170,8 @@ static ssize_t queue_max_discard_sectors_store(struct gendisk *disk,
170170
if ((max_discard_bytes >> SECTOR_SHIFT) > UINT_MAX)
171171
return -EINVAL;
172172

173-
lim = queue_limits_start_update(disk->queue);
174-
lim.max_user_discard_sectors = max_discard_bytes >> SECTOR_SHIFT;
175-
err = queue_limits_commit_update(disk->queue, &lim);
176-
if (err)
177-
return err;
178-
return ret;
173+
lim->max_user_discard_sectors = max_discard_bytes >> SECTOR_SHIFT;
174+
return 0;
179175
}
180176

181177
/*
@@ -190,46 +186,36 @@ static ssize_t queue_zone_append_max_show(struct gendisk *disk, char *page)
190186
SECTOR_SHIFT);
191187
}
192188

193-
static ssize_t
194-
queue_max_sectors_store(struct gendisk *disk, const char *page, size_t count)
189+
static int
190+
queue_max_sectors_store(struct gendisk *disk, const char *page, size_t count,
191+
struct queue_limits *lim)
195192
{
196193
unsigned long max_sectors_kb;
197-
struct queue_limits lim;
198194
ssize_t ret;
199-
int err;
200195

201196
ret = queue_var_store(&max_sectors_kb, page, count);
202197
if (ret < 0)
203198
return ret;
204199

205-
lim = queue_limits_start_update(disk->queue);
206-
lim.max_user_sectors = max_sectors_kb << 1;
207-
err = queue_limits_commit_update(disk->queue, &lim);
208-
if (err)
209-
return err;
210-
return ret;
200+
lim->max_user_sectors = max_sectors_kb << 1;
201+
return 0;
211202
}
212203

213204
static ssize_t queue_feature_store(struct gendisk *disk, const char *page,
214-
size_t count, blk_features_t feature)
205+
size_t count, struct queue_limits *lim, blk_features_t feature)
215206
{
216-
struct queue_limits lim;
217207
unsigned long val;
218208
ssize_t ret;
219209

220210
ret = queue_var_store(&val, page, count);
221211
if (ret < 0)
222212
return ret;
223213

224-
lim = queue_limits_start_update(disk->queue);
225214
if (val)
226-
lim.features |= feature;
215+
lim->features |= feature;
227216
else
228-
lim.features &= ~feature;
229-
ret = queue_limits_commit_update(disk->queue, &lim);
230-
if (ret)
231-
return ret;
232-
return count;
217+
lim->features &= ~feature;
218+
return 0;
233219
}
234220

235221
#define QUEUE_SYSFS_FEATURE(_name, _feature) \
@@ -238,10 +224,10 @@ static ssize_t queue_##_name##_show(struct gendisk *disk, char *page) \
238224
return sprintf(page, "%u\n", \
239225
!!(disk->queue->limits.features & _feature)); \
240226
} \
241-
static ssize_t queue_##_name##_store(struct gendisk *disk, \
242-
const char *page, size_t count) \
227+
static int queue_##_name##_store(struct gendisk *disk, \
228+
const char *page, size_t count, struct queue_limits *lim) \
243229
{ \
244-
return queue_feature_store(disk, page, count, _feature); \
230+
return queue_feature_store(disk, page, count, lim, _feature); \
245231
}
246232

247233
QUEUE_SYSFS_FEATURE(rotational, BLK_FEAT_ROTATIONAL)
@@ -381,12 +367,10 @@ static ssize_t queue_wc_show(struct gendisk *disk, char *page)
381367
return sprintf(page, "write through\n");
382368
}
383369

384-
static ssize_t queue_wc_store(struct gendisk *disk, const char *page,
385-
size_t count)
370+
static int queue_wc_store(struct gendisk *disk, const char *page,
371+
size_t count, struct queue_limits *lim)
386372
{
387-
struct queue_limits lim;
388373
bool disable;
389-
int err;
390374

391375
if (!strncmp(page, "write back", 10)) {
392376
disable = false;
@@ -397,15 +381,11 @@ static ssize_t queue_wc_store(struct gendisk *disk, const char *page,
397381
return -EINVAL;
398382
}
399383

400-
lim = queue_limits_start_update(disk->queue);
401384
if (disable)
402-
lim.flags |= BLK_FLAG_WRITE_CACHE_DISABLED;
385+
lim->flags |= BLK_FLAG_WRITE_CACHE_DISABLED;
403386
else
404-
lim.flags &= ~BLK_FLAG_WRITE_CACHE_DISABLED;
405-
err = queue_limits_commit_update(disk->queue, &lim);
406-
if (err)
407-
return err;
408-
return count;
387+
lim->flags &= ~BLK_FLAG_WRITE_CACHE_DISABLED;
388+
return 0;
409389
}
410390

411391
#define QUEUE_RO_ENTRY(_prefix, _name) \
@@ -421,6 +401,13 @@ static struct queue_sysfs_entry _prefix##_entry = { \
421401
.store = _prefix##_store, \
422402
};
423403

404+
#define QUEUE_LIM_RW_ENTRY(_prefix, _name) \
405+
static struct queue_sysfs_entry _prefix##_entry = { \
406+
.attr = { .name = _name, .mode = 0644 }, \
407+
.show = _prefix##_show, \
408+
.store_limit = _prefix##_store, \
409+
}
410+
424411
#define QUEUE_RW_LOAD_MODULE_ENTRY(_prefix, _name) \
425412
static struct queue_sysfs_entry _prefix##_entry = { \
426413
.attr = { .name = _name, .mode = 0644 }, \
@@ -431,7 +418,7 @@ static struct queue_sysfs_entry _prefix##_entry = { \
431418

432419
QUEUE_RW_ENTRY(queue_requests, "nr_requests");
433420
QUEUE_RW_ENTRY(queue_ra, "read_ahead_kb");
434-
QUEUE_RW_ENTRY(queue_max_sectors, "max_sectors_kb");
421+
QUEUE_LIM_RW_ENTRY(queue_max_sectors, "max_sectors_kb");
435422
QUEUE_RO_ENTRY(queue_max_hw_sectors, "max_hw_sectors_kb");
436423
QUEUE_RO_ENTRY(queue_max_segments, "max_segments");
437424
QUEUE_RO_ENTRY(queue_max_integrity_segments, "max_integrity_segments");
@@ -447,7 +434,7 @@ QUEUE_RO_ENTRY(queue_io_opt, "optimal_io_size");
447434
QUEUE_RO_ENTRY(queue_max_discard_segments, "max_discard_segments");
448435
QUEUE_RO_ENTRY(queue_discard_granularity, "discard_granularity");
449436
QUEUE_RO_ENTRY(queue_max_hw_discard_sectors, "discard_max_hw_bytes");
450-
QUEUE_RW_ENTRY(queue_max_discard_sectors, "discard_max_bytes");
437+
QUEUE_LIM_RW_ENTRY(queue_max_discard_sectors, "discard_max_bytes");
451438
QUEUE_RO_ENTRY(queue_discard_zeroes_data, "discard_zeroes_data");
452439

453440
QUEUE_RO_ENTRY(queue_atomic_write_max_sectors, "atomic_write_max_bytes");
@@ -470,7 +457,7 @@ QUEUE_RW_ENTRY(queue_nomerges, "nomerges");
470457
QUEUE_RW_ENTRY(queue_rq_affinity, "rq_affinity");
471458
QUEUE_RW_ENTRY(queue_poll, "io_poll");
472459
QUEUE_RW_ENTRY(queue_poll_delay, "io_poll_delay");
473-
QUEUE_RW_ENTRY(queue_wc, "write_cache");
460+
QUEUE_LIM_RW_ENTRY(queue_wc, "write_cache");
474461
QUEUE_RO_ENTRY(queue_fua, "fua");
475462
QUEUE_RO_ENTRY(queue_dax, "dax");
476463
QUEUE_RW_ENTRY(queue_io_timeout, "io_timeout");
@@ -483,10 +470,10 @@ static struct queue_sysfs_entry queue_hw_sector_size_entry = {
483470
.show = queue_logical_block_size_show,
484471
};
485472

486-
QUEUE_RW_ENTRY(queue_rotational, "rotational");
487-
QUEUE_RW_ENTRY(queue_iostats, "iostats");
488-
QUEUE_RW_ENTRY(queue_add_random, "add_random");
489-
QUEUE_RW_ENTRY(queue_stable_writes, "stable_writes");
473+
QUEUE_LIM_RW_ENTRY(queue_rotational, "rotational");
474+
QUEUE_LIM_RW_ENTRY(queue_iostats, "iostats");
475+
QUEUE_LIM_RW_ENTRY(queue_add_random, "add_random");
476+
QUEUE_LIM_RW_ENTRY(queue_stable_writes, "stable_writes");
490477

491478
#ifdef CONFIG_BLK_WBT
492479
static ssize_t queue_var_store64(s64 *var, const char *page)
@@ -683,7 +670,7 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
683670
struct request_queue *q = disk->queue;
684671
ssize_t res;
685672

686-
if (!entry->store)
673+
if (!entry->store_limit && !entry->store)
687674
return -EIO;
688675

689676
/*
@@ -694,11 +681,24 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
694681
if (entry->load_module)
695682
entry->load_module(disk, page, length);
696683

697-
blk_mq_freeze_queue(q);
698684
mutex_lock(&q->sysfs_lock);
699-
res = entry->store(disk, page, length);
700-
mutex_unlock(&q->sysfs_lock);
685+
blk_mq_freeze_queue(q);
686+
if (entry->store_limit) {
687+
struct queue_limits lim = queue_limits_start_update(q);
688+
689+
res = entry->store_limit(disk, page, length, &lim);
690+
if (res < 0) {
691+
queue_limits_cancel_update(q);
692+
} else {
693+
res = queue_limits_commit_update(q, &lim);
694+
if (!res)
695+
res = length;
696+
}
697+
} else {
698+
res = entry->store(disk, page, length);
699+
}
701700
blk_mq_unfreeze_queue(q);
701+
mutex_unlock(&q->sysfs_lock);
702702
return res;
703703
}
704704

0 commit comments

Comments
 (0)