null_blk: Fix zone reset all tracing
[linux-2.6-microblaze.git] / drivers / block / null_blk_zoned.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/vmalloc.h>
3 #include "null_blk.h"
4
5 #define CREATE_TRACE_POINTS
6 #include "null_blk_trace.h"
7
8 /* zone_size in MBs to sectors. */
9 #define ZONE_SIZE_SHIFT         11
10
11 static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect)
12 {
13         return sect >> ilog2(dev->zone_size_sects);
14 }
15
16 int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
17 {
18         sector_t dev_size = (sector_t)dev->size * 1024 * 1024;
19         sector_t sector = 0;
20         unsigned int i;
21
22         if (!is_power_of_2(dev->zone_size)) {
23                 pr_err("zone_size must be power-of-two\n");
24                 return -EINVAL;
25         }
26         if (dev->zone_size > dev->size) {
27                 pr_err("Zone size larger than device capacity\n");
28                 return -EINVAL;
29         }
30
31         if (!dev->zone_capacity)
32                 dev->zone_capacity = dev->zone_size;
33
34         if (dev->zone_capacity > dev->zone_size) {
35                 pr_err("null_blk: zone capacity (%lu MB) larger than zone size (%lu MB)\n",
36                                         dev->zone_capacity, dev->zone_size);
37                 return -EINVAL;
38         }
39
40         dev->zone_size_sects = dev->zone_size << ZONE_SIZE_SHIFT;
41         dev->nr_zones = dev_size >>
42                                 (SECTOR_SHIFT + ilog2(dev->zone_size_sects));
43         dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct blk_zone),
44                         GFP_KERNEL | __GFP_ZERO);
45         if (!dev->zones)
46                 return -ENOMEM;
47
48         spin_lock_init(&dev->zone_lock);
49         if (dev->zone_nr_conv >= dev->nr_zones) {
50                 dev->zone_nr_conv = dev->nr_zones - 1;
51                 pr_info("changed the number of conventional zones to %u",
52                         dev->zone_nr_conv);
53         }
54
55         /* Max active zones has to be < nbr of seq zones in order to be enforceable */
56         if (dev->zone_max_active >= dev->nr_zones - dev->zone_nr_conv) {
57                 dev->zone_max_active = 0;
58                 pr_info("zone_max_active limit disabled, limit >= zone count\n");
59         }
60
61         /* Max open zones has to be <= max active zones */
62         if (dev->zone_max_active && dev->zone_max_open > dev->zone_max_active) {
63                 dev->zone_max_open = dev->zone_max_active;
64                 pr_info("changed the maximum number of open zones to %u\n",
65                         dev->nr_zones);
66         } else if (dev->zone_max_open >= dev->nr_zones - dev->zone_nr_conv) {
67                 dev->zone_max_open = 0;
68                 pr_info("zone_max_open limit disabled, limit >= zone count\n");
69         }
70
71         for (i = 0; i <  dev->zone_nr_conv; i++) {
72                 struct blk_zone *zone = &dev->zones[i];
73
74                 zone->start = sector;
75                 zone->len = dev->zone_size_sects;
76                 zone->capacity = zone->len;
77                 zone->wp = zone->start + zone->len;
78                 zone->type = BLK_ZONE_TYPE_CONVENTIONAL;
79                 zone->cond = BLK_ZONE_COND_NOT_WP;
80
81                 sector += dev->zone_size_sects;
82         }
83
84         for (i = dev->zone_nr_conv; i < dev->nr_zones; i++) {
85                 struct blk_zone *zone = &dev->zones[i];
86
87                 zone->start = zone->wp = sector;
88                 zone->len = dev->zone_size_sects;
89                 zone->capacity = dev->zone_capacity << ZONE_SIZE_SHIFT;
90                 zone->type = BLK_ZONE_TYPE_SEQWRITE_REQ;
91                 zone->cond = BLK_ZONE_COND_EMPTY;
92
93                 sector += dev->zone_size_sects;
94         }
95
96         q->limits.zoned = BLK_ZONED_HM;
97         blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q);
98         blk_queue_required_elevator_features(q, ELEVATOR_F_ZBD_SEQ_WRITE);
99
100         return 0;
101 }
102
103 int null_register_zoned_dev(struct nullb *nullb)
104 {
105         struct nullb_device *dev = nullb->dev;
106         struct request_queue *q = nullb->q;
107
108         if (queue_is_mq(q)) {
109                 int ret = blk_revalidate_disk_zones(nullb->disk, NULL);
110
111                 if (ret)
112                         return ret;
113         } else {
114                 blk_queue_chunk_sectors(q, dev->zone_size_sects);
115                 q->nr_zones = blkdev_nr_zones(nullb->disk);
116         }
117
118         blk_queue_max_zone_append_sectors(q, dev->zone_size_sects);
119         blk_queue_max_open_zones(q, dev->zone_max_open);
120         blk_queue_max_active_zones(q, dev->zone_max_active);
121
122         return 0;
123 }
124
125 void null_free_zoned_dev(struct nullb_device *dev)
126 {
127         kvfree(dev->zones);
128 }
129
130 int null_report_zones(struct gendisk *disk, sector_t sector,
131                 unsigned int nr_zones, report_zones_cb cb, void *data)
132 {
133         struct nullb *nullb = disk->private_data;
134         struct nullb_device *dev = nullb->dev;
135         unsigned int first_zone, i;
136         struct blk_zone zone;
137         int error;
138
139         first_zone = null_zone_no(dev, sector);
140         if (first_zone >= dev->nr_zones)
141                 return 0;
142
143         nr_zones = min(nr_zones, dev->nr_zones - first_zone);
144         trace_nullb_report_zones(nullb, nr_zones);
145
146         for (i = 0; i < nr_zones; i++) {
147                 /*
148                  * Stacked DM target drivers will remap the zone information by
149                  * modifying the zone information passed to the report callback.
150                  * So use a local copy to avoid corruption of the device zone
151                  * array.
152                  */
153                 spin_lock_irq(&dev->zone_lock);
154                 memcpy(&zone, &dev->zones[first_zone + i],
155                        sizeof(struct blk_zone));
156                 spin_unlock_irq(&dev->zone_lock);
157
158                 error = cb(&zone, i, data);
159                 if (error)
160                         return error;
161         }
162
163         return nr_zones;
164 }
165
166 size_t null_zone_valid_read_len(struct nullb *nullb,
167                                 sector_t sector, unsigned int len)
168 {
169         struct nullb_device *dev = nullb->dev;
170         struct blk_zone *zone = &dev->zones[null_zone_no(dev, sector)];
171         unsigned int nr_sectors = len >> SECTOR_SHIFT;
172
173         /* Read must be below the write pointer position */
174         if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL ||
175             sector + nr_sectors <= zone->wp)
176                 return len;
177
178         if (sector > zone->wp)
179                 return 0;
180
181         return (zone->wp - sector) << SECTOR_SHIFT;
182 }
183
184 static blk_status_t null_close_zone(struct nullb_device *dev, struct blk_zone *zone)
185 {
186         if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
187                 return BLK_STS_IOERR;
188
189         switch (zone->cond) {
190         case BLK_ZONE_COND_CLOSED:
191                 /* close operation on closed is not an error */
192                 return BLK_STS_OK;
193         case BLK_ZONE_COND_IMP_OPEN:
194                 dev->nr_zones_imp_open--;
195                 break;
196         case BLK_ZONE_COND_EXP_OPEN:
197                 dev->nr_zones_exp_open--;
198                 break;
199         case BLK_ZONE_COND_EMPTY:
200         case BLK_ZONE_COND_FULL:
201         default:
202                 return BLK_STS_IOERR;
203         }
204
205         if (zone->wp == zone->start) {
206                 zone->cond = BLK_ZONE_COND_EMPTY;
207         } else {
208                 zone->cond = BLK_ZONE_COND_CLOSED;
209                 dev->nr_zones_closed++;
210         }
211
212         return BLK_STS_OK;
213 }
214
215 static void null_close_first_imp_zone(struct nullb_device *dev)
216 {
217         unsigned int i;
218
219         for (i = dev->zone_nr_conv; i < dev->nr_zones; i++) {
220                 if (dev->zones[i].cond == BLK_ZONE_COND_IMP_OPEN) {
221                         null_close_zone(dev, &dev->zones[i]);
222                         return;
223                 }
224         }
225 }
226
227 static blk_status_t null_check_active(struct nullb_device *dev)
228 {
229         if (!dev->zone_max_active)
230                 return BLK_STS_OK;
231
232         if (dev->nr_zones_exp_open + dev->nr_zones_imp_open +
233                         dev->nr_zones_closed < dev->zone_max_active)
234                 return BLK_STS_OK;
235
236         return BLK_STS_ZONE_ACTIVE_RESOURCE;
237 }
238
239 static blk_status_t null_check_open(struct nullb_device *dev)
240 {
241         if (!dev->zone_max_open)
242                 return BLK_STS_OK;
243
244         if (dev->nr_zones_exp_open + dev->nr_zones_imp_open < dev->zone_max_open)
245                 return BLK_STS_OK;
246
247         if (dev->nr_zones_imp_open) {
248                 if (null_check_active(dev) == BLK_STS_OK) {
249                         null_close_first_imp_zone(dev);
250                         return BLK_STS_OK;
251                 }
252         }
253
254         return BLK_STS_ZONE_OPEN_RESOURCE;
255 }
256
257 /*
258  * This function matches the manage open zone resources function in the ZBC standard,
259  * with the addition of max active zones support (added in the ZNS standard).
260  *
261  * The function determines if a zone can transition to implicit open or explicit open,
262  * while maintaining the max open zone (and max active zone) limit(s). It may close an
263  * implicit open zone in order to make additional zone resources available.
264  *
265  * ZBC states that an implicit open zone shall be closed only if there is not
266  * room within the open limit. However, with the addition of an active limit,
267  * it is not certain that closing an implicit open zone will allow a new zone
268  * to be opened, since we might already be at the active limit capacity.
269  */
270 static blk_status_t null_check_zone_resources(struct nullb_device *dev, struct blk_zone *zone)
271 {
272         blk_status_t ret;
273
274         switch (zone->cond) {
275         case BLK_ZONE_COND_EMPTY:
276                 ret = null_check_active(dev);
277                 if (ret != BLK_STS_OK)
278                         return ret;
279                 fallthrough;
280         case BLK_ZONE_COND_CLOSED:
281                 return null_check_open(dev);
282         default:
283                 /* Should never be called for other states */
284                 WARN_ON(1);
285                 return BLK_STS_IOERR;
286         }
287 }
288
289 static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
290                                     unsigned int nr_sectors, bool append)
291 {
292         struct nullb_device *dev = cmd->nq->dev;
293         unsigned int zno = null_zone_no(dev, sector);
294         struct blk_zone *zone = &dev->zones[zno];
295         blk_status_t ret;
296
297         trace_nullb_zone_op(cmd, zno, zone->cond);
298
299         if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
300                 return null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors);
301
302         switch (zone->cond) {
303         case BLK_ZONE_COND_FULL:
304                 /* Cannot write to a full zone */
305                 return BLK_STS_IOERR;
306         case BLK_ZONE_COND_EMPTY:
307         case BLK_ZONE_COND_CLOSED:
308                 ret = null_check_zone_resources(dev, zone);
309                 if (ret != BLK_STS_OK)
310                         return ret;
311                 break;
312         case BLK_ZONE_COND_IMP_OPEN:
313         case BLK_ZONE_COND_EXP_OPEN:
314                 break;
315         default:
316                 /* Invalid zone condition */
317                 return BLK_STS_IOERR;
318         }
319
320         /*
321          * Regular writes must be at the write pointer position.
322          * Zone append writes are automatically issued at the write
323          * pointer and the position returned using the request or BIO
324          * sector.
325          */
326         if (append) {
327                 sector = zone->wp;
328                 if (cmd->bio)
329                         cmd->bio->bi_iter.bi_sector = sector;
330                 else
331                         cmd->rq->__sector = sector;
332         } else if (sector != zone->wp) {
333                 return BLK_STS_IOERR;
334         }
335
336         if (zone->wp + nr_sectors > zone->start + zone->capacity)
337                 return BLK_STS_IOERR;
338
339         if (zone->cond == BLK_ZONE_COND_CLOSED) {
340                 dev->nr_zones_closed--;
341                 dev->nr_zones_imp_open++;
342         } else if (zone->cond == BLK_ZONE_COND_EMPTY) {
343                 dev->nr_zones_imp_open++;
344         }
345         if (zone->cond != BLK_ZONE_COND_EXP_OPEN)
346                 zone->cond = BLK_ZONE_COND_IMP_OPEN;
347
348         ret = null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors);
349         if (ret != BLK_STS_OK)
350                 return ret;
351
352         zone->wp += nr_sectors;
353         if (zone->wp == zone->start + zone->capacity) {
354                 if (zone->cond == BLK_ZONE_COND_EXP_OPEN)
355                         dev->nr_zones_exp_open--;
356                 else if (zone->cond == BLK_ZONE_COND_IMP_OPEN)
357                         dev->nr_zones_imp_open--;
358                 zone->cond = BLK_ZONE_COND_FULL;
359         }
360         return BLK_STS_OK;
361 }
362
363 static blk_status_t null_open_zone(struct nullb_device *dev, struct blk_zone *zone)
364 {
365         blk_status_t ret;
366
367         if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
368                 return BLK_STS_IOERR;
369
370         switch (zone->cond) {
371         case BLK_ZONE_COND_EXP_OPEN:
372                 /* open operation on exp open is not an error */
373                 return BLK_STS_OK;
374         case BLK_ZONE_COND_EMPTY:
375                 ret = null_check_zone_resources(dev, zone);
376                 if (ret != BLK_STS_OK)
377                         return ret;
378                 break;
379         case BLK_ZONE_COND_IMP_OPEN:
380                 dev->nr_zones_imp_open--;
381                 break;
382         case BLK_ZONE_COND_CLOSED:
383                 ret = null_check_zone_resources(dev, zone);
384                 if (ret != BLK_STS_OK)
385                         return ret;
386                 dev->nr_zones_closed--;
387                 break;
388         case BLK_ZONE_COND_FULL:
389         default:
390                 return BLK_STS_IOERR;
391         }
392
393         zone->cond = BLK_ZONE_COND_EXP_OPEN;
394         dev->nr_zones_exp_open++;
395
396         return BLK_STS_OK;
397 }
398
399 static blk_status_t null_finish_zone(struct nullb_device *dev, struct blk_zone *zone)
400 {
401         blk_status_t ret;
402
403         if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
404                 return BLK_STS_IOERR;
405
406         switch (zone->cond) {
407         case BLK_ZONE_COND_FULL:
408                 /* finish operation on full is not an error */
409                 return BLK_STS_OK;
410         case BLK_ZONE_COND_EMPTY:
411                 ret = null_check_zone_resources(dev, zone);
412                 if (ret != BLK_STS_OK)
413                         return ret;
414                 break;
415         case BLK_ZONE_COND_IMP_OPEN:
416                 dev->nr_zones_imp_open--;
417                 break;
418         case BLK_ZONE_COND_EXP_OPEN:
419                 dev->nr_zones_exp_open--;
420                 break;
421         case BLK_ZONE_COND_CLOSED:
422                 ret = null_check_zone_resources(dev, zone);
423                 if (ret != BLK_STS_OK)
424                         return ret;
425                 dev->nr_zones_closed--;
426                 break;
427         default:
428                 return BLK_STS_IOERR;
429         }
430
431         zone->cond = BLK_ZONE_COND_FULL;
432         zone->wp = zone->start + zone->len;
433
434         return BLK_STS_OK;
435 }
436
437 static blk_status_t null_reset_zone(struct nullb_device *dev, struct blk_zone *zone)
438 {
439         if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
440                 return BLK_STS_IOERR;
441
442         switch (zone->cond) {
443         case BLK_ZONE_COND_EMPTY:
444                 /* reset operation on empty is not an error */
445                 return BLK_STS_OK;
446         case BLK_ZONE_COND_IMP_OPEN:
447                 dev->nr_zones_imp_open--;
448                 break;
449         case BLK_ZONE_COND_EXP_OPEN:
450                 dev->nr_zones_exp_open--;
451                 break;
452         case BLK_ZONE_COND_CLOSED:
453                 dev->nr_zones_closed--;
454                 break;
455         case BLK_ZONE_COND_FULL:
456                 break;
457         default:
458                 return BLK_STS_IOERR;
459         }
460
461         zone->cond = BLK_ZONE_COND_EMPTY;
462         zone->wp = zone->start;
463
464         return BLK_STS_OK;
465 }
466
467 static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op,
468                                    sector_t sector)
469 {
470         struct nullb_device *dev = cmd->nq->dev;
471         unsigned int zone_no = null_zone_no(dev, sector);
472         struct blk_zone *zone = &dev->zones[zone_no];
473         blk_status_t ret = BLK_STS_OK;
474         size_t i;
475
476         switch (op) {
477         case REQ_OP_ZONE_RESET_ALL:
478                 for (i = dev->zone_nr_conv; i < dev->nr_zones; i++) {
479                         zone = &dev->zones[i];
480                         if (zone->cond != BLK_ZONE_COND_EMPTY) {
481                                 null_reset_zone(dev, zone);
482                                 trace_nullb_zone_op(cmd, i, zone->cond);
483                         }
484                 }
485                 return BLK_STS_OK;
486         case REQ_OP_ZONE_RESET:
487                 ret = null_reset_zone(dev, zone);
488                 break;
489         case REQ_OP_ZONE_OPEN:
490                 ret = null_open_zone(dev, zone);
491                 break;
492         case REQ_OP_ZONE_CLOSE:
493                 ret = null_close_zone(dev, zone);
494                 break;
495         case REQ_OP_ZONE_FINISH:
496                 ret = null_finish_zone(dev, zone);
497                 break;
498         default:
499                 return BLK_STS_NOTSUPP;
500         }
501
502         if (ret == BLK_STS_OK)
503                 trace_nullb_zone_op(cmd, zone_no, zone->cond);
504
505         return ret;
506 }
507
508 blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, enum req_opf op,
509                                     sector_t sector, sector_t nr_sectors)
510 {
511         blk_status_t sts;
512         struct nullb_device *dev = cmd->nq->dev;
513
514         spin_lock_irq(&dev->zone_lock);
515         switch (op) {
516         case REQ_OP_WRITE:
517                 sts = null_zone_write(cmd, sector, nr_sectors, false);
518                 break;
519         case REQ_OP_ZONE_APPEND:
520                 sts = null_zone_write(cmd, sector, nr_sectors, true);
521                 break;
522         case REQ_OP_ZONE_RESET:
523         case REQ_OP_ZONE_RESET_ALL:
524         case REQ_OP_ZONE_OPEN:
525         case REQ_OP_ZONE_CLOSE:
526         case REQ_OP_ZONE_FINISH:
527                 sts = null_zone_mgmt(cmd, op, sector);
528                 break;
529         default:
530                 sts = null_process_cmd(cmd, op, sector, nr_sectors);
531         }
532         spin_unlock_irq(&dev->zone_lock);
533
534         return sts;
535 }