block: add SPDX tags to block layer files missing licensing information
[sfrench/cifs-2.6.git] / block / blk-mq-sysfs.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/kernel.h>
3 #include <linux/module.h>
4 #include <linux/backing-dev.h>
5 #include <linux/bio.h>
6 #include <linux/blkdev.h>
7 #include <linux/mm.h>
8 #include <linux/init.h>
9 #include <linux/slab.h>
10 #include <linux/workqueue.h>
11 #include <linux/smp.h>
12
13 #include <linux/blk-mq.h>
14 #include "blk-mq.h"
15 #include "blk-mq-tag.h"
16
17 static void blk_mq_sysfs_release(struct kobject *kobj)
18 {
19         struct blk_mq_ctxs *ctxs = container_of(kobj, struct blk_mq_ctxs, kobj);
20
21         free_percpu(ctxs->queue_ctx);
22         kfree(ctxs);
23 }
24
25 static void blk_mq_ctx_sysfs_release(struct kobject *kobj)
26 {
27         struct blk_mq_ctx *ctx = container_of(kobj, struct blk_mq_ctx, kobj);
28
29         /* ctx->ctxs won't be released until all ctx are freed */
30         kobject_put(&ctx->ctxs->kobj);
31 }
32
33 static void blk_mq_hw_sysfs_release(struct kobject *kobj)
34 {
35         struct blk_mq_hw_ctx *hctx = container_of(kobj, struct blk_mq_hw_ctx,
36                                                   kobj);
37         free_cpumask_var(hctx->cpumask);
38         kfree(hctx->ctxs);
39         kfree(hctx);
40 }
41
42 struct blk_mq_ctx_sysfs_entry {
43         struct attribute attr;
44         ssize_t (*show)(struct blk_mq_ctx *, char *);
45         ssize_t (*store)(struct blk_mq_ctx *, const char *, size_t);
46 };
47
48 struct blk_mq_hw_ctx_sysfs_entry {
49         struct attribute attr;
50         ssize_t (*show)(struct blk_mq_hw_ctx *, char *);
51         ssize_t (*store)(struct blk_mq_hw_ctx *, const char *, size_t);
52 };
53
54 static ssize_t blk_mq_sysfs_show(struct kobject *kobj, struct attribute *attr,
55                                  char *page)
56 {
57         struct blk_mq_ctx_sysfs_entry *entry;
58         struct blk_mq_ctx *ctx;
59         struct request_queue *q;
60         ssize_t res;
61
62         entry = container_of(attr, struct blk_mq_ctx_sysfs_entry, attr);
63         ctx = container_of(kobj, struct blk_mq_ctx, kobj);
64         q = ctx->queue;
65
66         if (!entry->show)
67                 return -EIO;
68
69         res = -ENOENT;
70         mutex_lock(&q->sysfs_lock);
71         if (!blk_queue_dying(q))
72                 res = entry->show(ctx, page);
73         mutex_unlock(&q->sysfs_lock);
74         return res;
75 }
76
77 static ssize_t blk_mq_sysfs_store(struct kobject *kobj, struct attribute *attr,
78                                   const char *page, size_t length)
79 {
80         struct blk_mq_ctx_sysfs_entry *entry;
81         struct blk_mq_ctx *ctx;
82         struct request_queue *q;
83         ssize_t res;
84
85         entry = container_of(attr, struct blk_mq_ctx_sysfs_entry, attr);
86         ctx = container_of(kobj, struct blk_mq_ctx, kobj);
87         q = ctx->queue;
88
89         if (!entry->store)
90                 return -EIO;
91
92         res = -ENOENT;
93         mutex_lock(&q->sysfs_lock);
94         if (!blk_queue_dying(q))
95                 res = entry->store(ctx, page, length);
96         mutex_unlock(&q->sysfs_lock);
97         return res;
98 }
99
100 static ssize_t blk_mq_hw_sysfs_show(struct kobject *kobj,
101                                     struct attribute *attr, char *page)
102 {
103         struct blk_mq_hw_ctx_sysfs_entry *entry;
104         struct blk_mq_hw_ctx *hctx;
105         struct request_queue *q;
106         ssize_t res;
107
108         entry = container_of(attr, struct blk_mq_hw_ctx_sysfs_entry, attr);
109         hctx = container_of(kobj, struct blk_mq_hw_ctx, kobj);
110         q = hctx->queue;
111
112         if (!entry->show)
113                 return -EIO;
114
115         res = -ENOENT;
116         mutex_lock(&q->sysfs_lock);
117         if (!blk_queue_dying(q))
118                 res = entry->show(hctx, page);
119         mutex_unlock(&q->sysfs_lock);
120         return res;
121 }
122
123 static ssize_t blk_mq_hw_sysfs_store(struct kobject *kobj,
124                                      struct attribute *attr, const char *page,
125                                      size_t length)
126 {
127         struct blk_mq_hw_ctx_sysfs_entry *entry;
128         struct blk_mq_hw_ctx *hctx;
129         struct request_queue *q;
130         ssize_t res;
131
132         entry = container_of(attr, struct blk_mq_hw_ctx_sysfs_entry, attr);
133         hctx = container_of(kobj, struct blk_mq_hw_ctx, kobj);
134         q = hctx->queue;
135
136         if (!entry->store)
137                 return -EIO;
138
139         res = -ENOENT;
140         mutex_lock(&q->sysfs_lock);
141         if (!blk_queue_dying(q))
142                 res = entry->store(hctx, page, length);
143         mutex_unlock(&q->sysfs_lock);
144         return res;
145 }
146
147 static ssize_t blk_mq_hw_sysfs_nr_tags_show(struct blk_mq_hw_ctx *hctx,
148                                             char *page)
149 {
150         return sprintf(page, "%u\n", hctx->tags->nr_tags);
151 }
152
153 static ssize_t blk_mq_hw_sysfs_nr_reserved_tags_show(struct blk_mq_hw_ctx *hctx,
154                                                      char *page)
155 {
156         return sprintf(page, "%u\n", hctx->tags->nr_reserved_tags);
157 }
158
159 static ssize_t blk_mq_hw_sysfs_cpus_show(struct blk_mq_hw_ctx *hctx, char *page)
160 {
161         unsigned int i, first = 1;
162         ssize_t ret = 0;
163
164         for_each_cpu(i, hctx->cpumask) {
165                 if (first)
166                         ret += sprintf(ret + page, "%u", i);
167                 else
168                         ret += sprintf(ret + page, ", %u", i);
169
170                 first = 0;
171         }
172
173         ret += sprintf(ret + page, "\n");
174         return ret;
175 }
176
177 static struct attribute *default_ctx_attrs[] = {
178         NULL,
179 };
180
181 static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_nr_tags = {
182         .attr = {.name = "nr_tags", .mode = 0444 },
183         .show = blk_mq_hw_sysfs_nr_tags_show,
184 };
185 static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_nr_reserved_tags = {
186         .attr = {.name = "nr_reserved_tags", .mode = 0444 },
187         .show = blk_mq_hw_sysfs_nr_reserved_tags_show,
188 };
189 static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_cpus = {
190         .attr = {.name = "cpu_list", .mode = 0444 },
191         .show = blk_mq_hw_sysfs_cpus_show,
192 };
193
194 static struct attribute *default_hw_ctx_attrs[] = {
195         &blk_mq_hw_sysfs_nr_tags.attr,
196         &blk_mq_hw_sysfs_nr_reserved_tags.attr,
197         &blk_mq_hw_sysfs_cpus.attr,
198         NULL,
199 };
200
201 static const struct sysfs_ops blk_mq_sysfs_ops = {
202         .show   = blk_mq_sysfs_show,
203         .store  = blk_mq_sysfs_store,
204 };
205
206 static const struct sysfs_ops blk_mq_hw_sysfs_ops = {
207         .show   = blk_mq_hw_sysfs_show,
208         .store  = blk_mq_hw_sysfs_store,
209 };
210
211 static struct kobj_type blk_mq_ktype = {
212         .sysfs_ops      = &blk_mq_sysfs_ops,
213         .release        = blk_mq_sysfs_release,
214 };
215
216 static struct kobj_type blk_mq_ctx_ktype = {
217         .sysfs_ops      = &blk_mq_sysfs_ops,
218         .default_attrs  = default_ctx_attrs,
219         .release        = blk_mq_ctx_sysfs_release,
220 };
221
222 static struct kobj_type blk_mq_hw_ktype = {
223         .sysfs_ops      = &blk_mq_hw_sysfs_ops,
224         .default_attrs  = default_hw_ctx_attrs,
225         .release        = blk_mq_hw_sysfs_release,
226 };
227
228 static void blk_mq_unregister_hctx(struct blk_mq_hw_ctx *hctx)
229 {
230         struct blk_mq_ctx *ctx;
231         int i;
232
233         if (!hctx->nr_ctx)
234                 return;
235
236         hctx_for_each_ctx(hctx, ctx, i)
237                 kobject_del(&ctx->kobj);
238
239         kobject_del(&hctx->kobj);
240 }
241
242 static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
243 {
244         struct request_queue *q = hctx->queue;
245         struct blk_mq_ctx *ctx;
246         int i, ret;
247
248         if (!hctx->nr_ctx)
249                 return 0;
250
251         ret = kobject_add(&hctx->kobj, q->mq_kobj, "%u", hctx->queue_num);
252         if (ret)
253                 return ret;
254
255         hctx_for_each_ctx(hctx, ctx, i) {
256                 ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu);
257                 if (ret)
258                         break;
259         }
260
261         return ret;
262 }
263
264 void blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
265 {
266         struct blk_mq_hw_ctx *hctx;
267         int i;
268
269         lockdep_assert_held(&q->sysfs_lock);
270
271         queue_for_each_hw_ctx(q, hctx, i)
272                 blk_mq_unregister_hctx(hctx);
273
274         kobject_uevent(q->mq_kobj, KOBJ_REMOVE);
275         kobject_del(q->mq_kobj);
276         kobject_put(&dev->kobj);
277
278         q->mq_sysfs_init_done = false;
279 }
280
281 void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx)
282 {
283         kobject_init(&hctx->kobj, &blk_mq_hw_ktype);
284 }
285
286 void blk_mq_sysfs_deinit(struct request_queue *q)
287 {
288         struct blk_mq_ctx *ctx;
289         int cpu;
290
291         for_each_possible_cpu(cpu) {
292                 ctx = per_cpu_ptr(q->queue_ctx, cpu);
293                 kobject_put(&ctx->kobj);
294         }
295         kobject_put(q->mq_kobj);
296 }
297
298 void blk_mq_sysfs_init(struct request_queue *q)
299 {
300         struct blk_mq_ctx *ctx;
301         int cpu;
302
303         kobject_init(q->mq_kobj, &blk_mq_ktype);
304
305         for_each_possible_cpu(cpu) {
306                 ctx = per_cpu_ptr(q->queue_ctx, cpu);
307
308                 kobject_get(q->mq_kobj);
309                 kobject_init(&ctx->kobj, &blk_mq_ctx_ktype);
310         }
311 }
312
313 int __blk_mq_register_dev(struct device *dev, struct request_queue *q)
314 {
315         struct blk_mq_hw_ctx *hctx;
316         int ret, i;
317
318         WARN_ON_ONCE(!q->kobj.parent);
319         lockdep_assert_held(&q->sysfs_lock);
320
321         ret = kobject_add(q->mq_kobj, kobject_get(&dev->kobj), "%s", "mq");
322         if (ret < 0)
323                 goto out;
324
325         kobject_uevent(q->mq_kobj, KOBJ_ADD);
326
327         queue_for_each_hw_ctx(q, hctx, i) {
328                 ret = blk_mq_register_hctx(hctx);
329                 if (ret)
330                         goto unreg;
331         }
332
333         q->mq_sysfs_init_done = true;
334
335 out:
336         return ret;
337
338 unreg:
339         while (--i >= 0)
340                 blk_mq_unregister_hctx(q->queue_hw_ctx[i]);
341
342         kobject_uevent(q->mq_kobj, KOBJ_REMOVE);
343         kobject_del(q->mq_kobj);
344         kobject_put(&dev->kobj);
345         return ret;
346 }
347
348 int blk_mq_register_dev(struct device *dev, struct request_queue *q)
349 {
350         int ret;
351
352         mutex_lock(&q->sysfs_lock);
353         ret = __blk_mq_register_dev(dev, q);
354         mutex_unlock(&q->sysfs_lock);
355
356         return ret;
357 }
358
359 void blk_mq_sysfs_unregister(struct request_queue *q)
360 {
361         struct blk_mq_hw_ctx *hctx;
362         int i;
363
364         mutex_lock(&q->sysfs_lock);
365         if (!q->mq_sysfs_init_done)
366                 goto unlock;
367
368         queue_for_each_hw_ctx(q, hctx, i)
369                 blk_mq_unregister_hctx(hctx);
370
371 unlock:
372         mutex_unlock(&q->sysfs_lock);
373 }
374
375 int blk_mq_sysfs_register(struct request_queue *q)
376 {
377         struct blk_mq_hw_ctx *hctx;
378         int i, ret = 0;
379
380         mutex_lock(&q->sysfs_lock);
381         if (!q->mq_sysfs_init_done)
382                 goto unlock;
383
384         queue_for_each_hw_ctx(q, hctx, i) {
385                 ret = blk_mq_register_hctx(hctx);
386                 if (ret)
387                         break;
388         }
389
390 unlock:
391         mutex_unlock(&q->sysfs_lock);
392
393         return ret;
394 }