Blame view
block/blk-mq-sysfs.c
8.52 KB
3dcf60bcb block: add SPDX t... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
320ae51fe blk-mq: new multi... |
2 3 4 5 6 7 8 9 10 11 12 13 |
#include <linux/kernel.h> #include <linux/module.h> #include <linux/backing-dev.h> #include <linux/bio.h> #include <linux/blkdev.h> #include <linux/mm.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/workqueue.h> #include <linux/smp.h> #include <linux/blk-mq.h> |
c7e2d94b3 blk-mq: free hw q... |
14 |
#include "blk.h" |
320ae51fe blk-mq: new multi... |
15 16 17 18 19 |
#include "blk-mq.h" #include "blk-mq-tag.h" static void blk_mq_sysfs_release(struct kobject *kobj) { |
1db4909e7 blk-mq: not embed... |
20 21 22 23 24 25 26 27 28 29 30 31 |
struct blk_mq_ctxs *ctxs = container_of(kobj, struct blk_mq_ctxs, kobj); free_percpu(ctxs->queue_ctx); kfree(ctxs); } static void blk_mq_ctx_sysfs_release(struct kobject *kobj) { struct blk_mq_ctx *ctx = container_of(kobj, struct blk_mq_ctx, kobj); /* ctx->ctxs won't be released until all ctx are freed */ kobject_put(&ctx->ctxs->kobj); |
320ae51fe blk-mq: new multi... |
32 |
} |
6c8b232ef blk-mq: make life... |
33 34 35 36 |
static void blk_mq_hw_sysfs_release(struct kobject *kobj) { struct blk_mq_hw_ctx *hctx = container_of(kobj, struct blk_mq_hw_ctx, kobj); |
c7e2d94b3 blk-mq: free hw q... |
37 |
|
1b97871b5 blk-mq: move canc... |
38 |
cancel_delayed_work_sync(&hctx->run_work); |
c7e2d94b3 blk-mq: free hw q... |
39 40 41 42 |
if (hctx->flags & BLK_MQ_F_BLOCKING) cleanup_srcu_struct(hctx->srcu); blk_free_flush_queue(hctx->fq); sbitmap_free(&hctx->ctx_map); |
01388df37 blk-mq: free hctx... |
43 |
free_cpumask_var(hctx->cpumask); |
6c8b232ef blk-mq: make life... |
44 45 46 |
kfree(hctx->ctxs); kfree(hctx); } |
320ae51fe blk-mq: new multi... |
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
struct blk_mq_ctx_sysfs_entry { struct attribute attr; ssize_t (*show)(struct blk_mq_ctx *, char *); ssize_t (*store)(struct blk_mq_ctx *, const char *, size_t); }; struct blk_mq_hw_ctx_sysfs_entry { struct attribute attr; ssize_t (*show)(struct blk_mq_hw_ctx *, char *); ssize_t (*store)(struct blk_mq_hw_ctx *, const char *, size_t); }; static ssize_t blk_mq_sysfs_show(struct kobject *kobj, struct attribute *attr, char *page) { struct blk_mq_ctx_sysfs_entry *entry; struct blk_mq_ctx *ctx; struct request_queue *q; ssize_t res; entry = container_of(attr, struct blk_mq_ctx_sysfs_entry, attr); ctx = container_of(kobj, struct blk_mq_ctx, kobj); q = ctx->queue; if (!entry->show) return -EIO; res = -ENOENT; mutex_lock(&q->sysfs_lock); if (!blk_queue_dying(q)) res = entry->show(ctx, page); mutex_unlock(&q->sysfs_lock); return res; } static ssize_t blk_mq_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *page, size_t length) { struct blk_mq_ctx_sysfs_entry *entry; struct blk_mq_ctx *ctx; struct request_queue *q; ssize_t res; entry = container_of(attr, struct blk_mq_ctx_sysfs_entry, attr); ctx = container_of(kobj, struct blk_mq_ctx, kobj); q = ctx->queue; if (!entry->store) return -EIO; res = -ENOENT; mutex_lock(&q->sysfs_lock); if (!blk_queue_dying(q)) res = entry->store(ctx, page, length); mutex_unlock(&q->sysfs_lock); return res; } static ssize_t blk_mq_hw_sysfs_show(struct kobject *kobj, struct attribute *attr, char *page) { struct blk_mq_hw_ctx_sysfs_entry *entry; struct blk_mq_hw_ctx *hctx; struct request_queue *q; ssize_t res; entry = container_of(attr, struct blk_mq_hw_ctx_sysfs_entry, attr); hctx = container_of(kobj, struct blk_mq_hw_ctx, kobj); q = hctx->queue; if (!entry->show) return -EIO; res = -ENOENT; mutex_lock(&q->sysfs_lock); if (!blk_queue_dying(q)) res = entry->show(hctx, page); mutex_unlock(&q->sysfs_lock); return res; } static ssize_t blk_mq_hw_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *page, size_t length) { struct blk_mq_hw_ctx_sysfs_entry *entry; struct blk_mq_hw_ctx *hctx; struct request_queue *q; ssize_t res; entry = container_of(attr, struct blk_mq_hw_ctx_sysfs_entry, attr); hctx = container_of(kobj, struct blk_mq_hw_ctx, kobj); q = hctx->queue; if (!entry->store) return -EIO; res = -ENOENT; mutex_lock(&q->sysfs_lock); if (!blk_queue_dying(q)) res = entry->store(hctx, page, length); mutex_unlock(&q->sysfs_lock); return res; } |
d96b37c0a blk-mq: move tags... |
151 152 |
static ssize_t blk_mq_hw_sysfs_nr_tags_show(struct blk_mq_hw_ctx *hctx, char *page) |
bd166ef18 blk-mq-sched: add... |
153 |
{ |
d96b37c0a blk-mq: move tags... |
154 155 |
return sprintf(page, "%u ", hctx->tags->nr_tags); |
bd166ef18 blk-mq-sched: add... |
156 |
} |
d96b37c0a blk-mq: move tags... |
157 158 |
static ssize_t blk_mq_hw_sysfs_nr_reserved_tags_show(struct blk_mq_hw_ctx *hctx, char *page) |
320ae51fe blk-mq: new multi... |
159 |
{ |
d96b37c0a blk-mq: move tags... |
160 161 |
return sprintf(page, "%u ", hctx->tags->nr_reserved_tags); |
320ae51fe blk-mq: new multi... |
162 |
} |
676141e48 blk-mq: don't dum... |
163 164 |
static ssize_t blk_mq_hw_sysfs_cpus_show(struct blk_mq_hw_ctx *hctx, char *page) { |
285b07348 blk-mq: avoid sys... |
165 |
const size_t size = PAGE_SIZE - 1; |
cb2da43e3 blk-mq: simplify ... |
166 |
unsigned int i, first = 1; |
285b07348 blk-mq: avoid sys... |
167 |
int ret = 0, pos = 0; |
676141e48 blk-mq: don't dum... |
168 |
|
cb2da43e3 blk-mq: simplify ... |
169 |
for_each_cpu(i, hctx->cpumask) { |
676141e48 blk-mq: don't dum... |
170 |
if (first) |
285b07348 blk-mq: avoid sys... |
171 |
ret = snprintf(pos + page, size - pos, "%u", i); |
676141e48 blk-mq: don't dum... |
172 |
else |
285b07348 blk-mq: avoid sys... |
173 174 175 176 |
ret = snprintf(pos + page, size - pos, ", %u", i); if (ret >= size - pos) break; |
676141e48 blk-mq: don't dum... |
177 178 |
first = 0; |
285b07348 blk-mq: avoid sys... |
179 |
pos += ret; |
676141e48 blk-mq: don't dum... |
180 |
} |
e13c3c219 blk-mq: make sure... |
181 182 |
ret = snprintf(pos + page, size + 1 - pos, " "); |
285b07348 blk-mq: avoid sys... |
183 |
return pos + ret; |
676141e48 blk-mq: don't dum... |
184 |
} |
d96b37c0a blk-mq: move tags... |
185 |
static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_nr_tags = { |
5657a819a block drivers/blo... |
186 |
.attr = {.name = "nr_tags", .mode = 0444 }, |
d96b37c0a blk-mq: move tags... |
187 188 189 |
.show = blk_mq_hw_sysfs_nr_tags_show, }; static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_nr_reserved_tags = { |
5657a819a block drivers/blo... |
190 |
.attr = {.name = "nr_reserved_tags", .mode = 0444 }, |
d96b37c0a blk-mq: move tags... |
191 192 |
.show = blk_mq_hw_sysfs_nr_reserved_tags_show, }; |
676141e48 blk-mq: don't dum... |
193 |
static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_cpus = { |
5657a819a block drivers/blo... |
194 |
.attr = {.name = "cpu_list", .mode = 0444 }, |
676141e48 blk-mq: don't dum... |
195 196 |
.show = blk_mq_hw_sysfs_cpus_show, }; |
320ae51fe blk-mq: new multi... |
197 198 |
static struct attribute *default_hw_ctx_attrs[] = { |
d96b37c0a blk-mq: move tags... |
199 200 |
&blk_mq_hw_sysfs_nr_tags.attr, &blk_mq_hw_sysfs_nr_reserved_tags.attr, |
676141e48 blk-mq: don't dum... |
201 |
&blk_mq_hw_sysfs_cpus.attr, |
320ae51fe blk-mq: new multi... |
202 203 |
NULL, }; |
800f5aa1e block: Replace al... |
204 |
ATTRIBUTE_GROUPS(default_hw_ctx); |
320ae51fe blk-mq: new multi... |
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
static const struct sysfs_ops blk_mq_sysfs_ops = { .show = blk_mq_sysfs_show, .store = blk_mq_sysfs_store, }; static const struct sysfs_ops blk_mq_hw_sysfs_ops = { .show = blk_mq_hw_sysfs_show, .store = blk_mq_hw_sysfs_store, }; static struct kobj_type blk_mq_ktype = { .sysfs_ops = &blk_mq_sysfs_ops, .release = blk_mq_sysfs_release, }; static struct kobj_type blk_mq_ctx_ktype = { .sysfs_ops = &blk_mq_sysfs_ops, |
1db4909e7 blk-mq: not embed... |
223 |
.release = blk_mq_ctx_sysfs_release, |
320ae51fe blk-mq: new multi... |
224 225 226 227 |
}; static struct kobj_type blk_mq_hw_ktype = { .sysfs_ops = &blk_mq_hw_sysfs_ops, |
800f5aa1e block: Replace al... |
228 |
.default_groups = default_hw_ctx_groups, |
6c8b232ef blk-mq: make life... |
229 |
.release = blk_mq_hw_sysfs_release, |
320ae51fe blk-mq: new multi... |
230 |
}; |
ee3c5db08 blk-mq: blk_mq_un... |
231 |
static void blk_mq_unregister_hctx(struct blk_mq_hw_ctx *hctx) |
67aec14ce blk-mq: make the ... |
232 233 234 |
{ struct blk_mq_ctx *ctx; int i; |
4593fdbe7 blk-mq: fix sysfs... |
235 |
if (!hctx->nr_ctx) |
67aec14ce blk-mq: make the ... |
236 237 238 239 240 241 242 |
return; hctx_for_each_ctx(hctx, ctx, i) kobject_del(&ctx->kobj); kobject_del(&hctx->kobj); } |
ee3c5db08 blk-mq: blk_mq_un... |
243 |
static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx) |
67aec14ce blk-mq: make the ... |
244 245 246 247 |
{ struct request_queue *q = hctx->queue; struct blk_mq_ctx *ctx; int i, ret; |
4593fdbe7 blk-mq: fix sysfs... |
248 |
if (!hctx->nr_ctx) |
67aec14ce blk-mq: make the ... |
249 |
return 0; |
1db4909e7 blk-mq: not embed... |
250 |
ret = kobject_add(&hctx->kobj, q->mq_kobj, "%u", hctx->queue_num); |
67aec14ce blk-mq: make the ... |
251 252 253 254 255 256 257 258 259 260 261 |
if (ret) return ret; hctx_for_each_ctx(hctx, ctx, i) { ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu); if (ret) break; } return ret; } |
667257e8b block: properly p... |
262 |
void blk_mq_unregister_dev(struct device *dev, struct request_queue *q) |
320ae51fe blk-mq: new multi... |
263 |
{ |
851573660 block: fix memory... |
264 |
struct blk_mq_hw_ctx *hctx; |
7ea5fe31c blk-mq: make life... |
265 |
int i; |
851573660 block: fix memory... |
266 |
|
cecf5d87f block: split .sys... |
267 |
lockdep_assert_held(&q->sysfs_dir_lock); |
2d0364c8c blk-mq: Register ... |
268 |
|
6c8b232ef blk-mq: make life... |
269 |
queue_for_each_hw_ctx(q, hctx, i) |
67aec14ce blk-mq: make the ... |
270 |
blk_mq_unregister_hctx(hctx); |
1db4909e7 blk-mq: not embed... |
271 272 |
kobject_uevent(q->mq_kobj, KOBJ_REMOVE); kobject_del(q->mq_kobj); |
b21d5b301 blk-mq: register ... |
273 |
kobject_put(&dev->kobj); |
4593fdbe7 blk-mq: fix sysfs... |
274 275 |
q->mq_sysfs_init_done = false; |
c0f3fd2b3 blk-mq: fix deadl... |
276 |
} |
868f2f0b7 blk-mq: dynamic h... |
277 278 279 280 |
void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx) { kobject_init(&hctx->kobj, &blk_mq_hw_ktype); } |
7ea5fe31c blk-mq: make life... |
281 282 283 284 285 286 287 288 289 |
void blk_mq_sysfs_deinit(struct request_queue *q) { struct blk_mq_ctx *ctx; int cpu; for_each_possible_cpu(cpu) { ctx = per_cpu_ptr(q->queue_ctx, cpu); kobject_put(&ctx->kobj); } |
1db4909e7 blk-mq: not embed... |
290 |
kobject_put(q->mq_kobj); |
7ea5fe31c blk-mq: make life... |
291 |
} |
737f98cfe blk-mq: initializ... |
292 |
void blk_mq_sysfs_init(struct request_queue *q) |
67aec14ce blk-mq: make the ... |
293 |
{ |
67aec14ce blk-mq: make the ... |
294 |
struct blk_mq_ctx *ctx; |
897bb0c7f blk-mq: Use prope... |
295 |
int cpu; |
67aec14ce blk-mq: make the ... |
296 |
|
1db4909e7 blk-mq: not embed... |
297 |
kobject_init(q->mq_kobj, &blk_mq_ktype); |
67aec14ce blk-mq: make the ... |
298 |
|
897bb0c7f blk-mq: Use prope... |
299 300 |
for_each_possible_cpu(cpu) { ctx = per_cpu_ptr(q->queue_ctx, cpu); |
1db4909e7 blk-mq: not embed... |
301 302 |
kobject_get(q->mq_kobj); |
06a41a99d blk-mq: Fix unini... |
303 |
kobject_init(&ctx->kobj, &blk_mq_ctx_ktype); |
897bb0c7f blk-mq: Use prope... |
304 |
} |
67aec14ce blk-mq: make the ... |
305 |
} |
2d0364c8c blk-mq: Register ... |
306 |
int __blk_mq_register_dev(struct device *dev, struct request_queue *q) |
320ae51fe blk-mq: new multi... |
307 |
{ |
320ae51fe blk-mq: new multi... |
308 |
struct blk_mq_hw_ctx *hctx; |
67aec14ce blk-mq: make the ... |
309 |
int ret, i; |
320ae51fe blk-mq: new multi... |
310 |
|
2d0364c8c blk-mq: Register ... |
311 |
WARN_ON_ONCE(!q->kobj.parent); |
cecf5d87f block: split .sys... |
312 |
lockdep_assert_held(&q->sysfs_dir_lock); |
4593fdbe7 blk-mq: fix sysfs... |
313 |
|
1db4909e7 blk-mq: not embed... |
314 |
ret = kobject_add(q->mq_kobj, kobject_get(&dev->kobj), "%s", "mq"); |
320ae51fe blk-mq: new multi... |
315 |
if (ret < 0) |
4593fdbe7 blk-mq: fix sysfs... |
316 |
goto out; |
320ae51fe blk-mq: new multi... |
317 |
|
1db4909e7 blk-mq: not embed... |
318 |
kobject_uevent(q->mq_kobj, KOBJ_ADD); |
320ae51fe blk-mq: new multi... |
319 320 |
queue_for_each_hw_ctx(q, hctx, i) { |
67aec14ce blk-mq: make the ... |
321 |
ret = blk_mq_register_hctx(hctx); |
320ae51fe blk-mq: new multi... |
322 |
if (ret) |
f05d1ba78 blk-mq: Only unre... |
323 |
goto unreg; |
320ae51fe blk-mq: new multi... |
324 |
} |
f05d1ba78 blk-mq: Only unre... |
325 |
q->mq_sysfs_init_done = true; |
2d0364c8c blk-mq: Register ... |
326 |
|
4593fdbe7 blk-mq: fix sysfs... |
327 |
out: |
2d0364c8c blk-mq: Register ... |
328 |
return ret; |
f05d1ba78 blk-mq: Only unre... |
329 330 331 332 |
unreg: while (--i >= 0) blk_mq_unregister_hctx(q->queue_hw_ctx[i]); |
1db4909e7 blk-mq: not embed... |
333 334 |
kobject_uevent(q->mq_kobj, KOBJ_REMOVE); kobject_del(q->mq_kobj); |
f05d1ba78 blk-mq: Only unre... |
335 336 |
kobject_put(&dev->kobj); return ret; |
2d0364c8c blk-mq: Register ... |
337 |
} |
67aec14ce blk-mq: make the ... |
338 339 340 341 |
void blk_mq_sysfs_unregister(struct request_queue *q) { struct blk_mq_hw_ctx *hctx; int i; |
cecf5d87f block: split .sys... |
342 |
mutex_lock(&q->sysfs_dir_lock); |
4593fdbe7 blk-mq: fix sysfs... |
343 |
if (!q->mq_sysfs_init_done) |
2d0364c8c blk-mq: Register ... |
344 |
goto unlock; |
4593fdbe7 blk-mq: fix sysfs... |
345 |
|
67aec14ce blk-mq: make the ... |
346 347 |
queue_for_each_hw_ctx(q, hctx, i) blk_mq_unregister_hctx(hctx); |
2d0364c8c blk-mq: Register ... |
348 349 |
unlock: |
cecf5d87f block: split .sys... |
350 |
mutex_unlock(&q->sysfs_dir_lock); |
67aec14ce blk-mq: make the ... |
351 352 353 354 355 356 |
} int blk_mq_sysfs_register(struct request_queue *q) { struct blk_mq_hw_ctx *hctx; int i, ret = 0; |
cecf5d87f block: split .sys... |
357 |
mutex_lock(&q->sysfs_dir_lock); |
4593fdbe7 blk-mq: fix sysfs... |
358 |
if (!q->mq_sysfs_init_done) |
2d0364c8c blk-mq: Register ... |
359 |
goto unlock; |
4593fdbe7 blk-mq: fix sysfs... |
360 |
|
67aec14ce blk-mq: make the ... |
361 362 363 364 365 |
queue_for_each_hw_ctx(q, hctx, i) { ret = blk_mq_register_hctx(hctx); if (ret) break; } |
2d0364c8c blk-mq: Register ... |
366 |
unlock: |
cecf5d87f block: split .sys... |
367 |
mutex_unlock(&q->sysfs_dir_lock); |
2d0364c8c blk-mq: Register ... |
368 |
|
67aec14ce blk-mq: make the ... |
369 370 |
return ret; } |