All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] block: introduce REQ_OP_ZONE_RESET_ALL
@ 2019-07-31 21:00 Chaitanya Kulkarni
  2019-07-31 21:00 ` [PATCH 1/4] block: add req op to reset all zones and flag Chaitanya Kulkarni
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Chaitanya Kulkarni @ 2019-07-31 21:00 UTC (permalink / raw)
  To: linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, damien.lemoal, sagi, dennisszhou,
	jthumshirn, osandov, ming.lei, tj, bvanassche, martin.petersen,
	Chaitanya Kulkarni

Hi,

In current implementation Zoned block device issues one bio at a time
based on the range of the offset and zones specified from userspace
tools like blkzone. Worst case scenario it will issue N requests which
are equal to the number of the zones when the application wants to
reset the drive, e.g. mkfs.

Zone Block devices allow issuing zone reset all operation [1] 
which can essentially reset all the available zones with only one
command.

This patch series introduces new REQ_OP_ZONE_RESET_ALL operation. Along
with that, we also introduce QUEUE_FLAG_ZONE_RESETALL (and respective
helpers) which is needed to be set by the low-level driver in order to
enable the REQ_OP_ZONE_RESET_ALL.

In this series we implement the REQ_OP_ZONE_RESET_ALL for sd and
null_blk block drivers.

Following is the performance difference measured for null_blk when
configured with 16TB size with zone size = 64MB for collecting
the overhead only for the Linux Block Layer. Please note that this
doesn't include any device overhead which will be additional on the
top of these numbers.

# modprobe null_blk zone_size=64 gb=16384 nr_devices=1 zoned=1
# for i in 1 2 3 4 5 ; do time blkzone reset /dev/nullb0 ; done 

------------------------------------------------------
| Time |  REQ_OP_ZONE_RESET | REQ_OP_ZONE_RESET_ALL |
------------------------------------------------------
| real |            0m4.622s|               0m0.014s|
| user |            0m0.000s|               0m0.000s|
| sys  |            0m2.762s|               0m0.011s|
|---------------------------------------------------|
| real |            0m4.565s|               0m0.013s|
| user |            0m0.000s|               0m0.000s|
| sys  |            0m2.729s|               0m0.010s|
|---------------------------------------------------|
| real |            0m4.536s|               0m0.013s|
| user |            0m0.001s|               0m0.000s|
| sys  |            0m2.703s|               0m0.011s|
|---------------------------------------------------|
| real |            0m4.619s|               0m0.013s|
| user |            0m0.001s|               0m0.002s|
| sys  |            0m2.759s|               0m0.009s|
|---------------------------------------------------|
| real |            0m4.529s|               0m0.012s|
| user |            0m0.002s|               0m0.000s|
| sys  |            0m2.696s|               0m0.010s|
------------------------------------------------------

In case anyone is interested please have a look at the test log.
We mainly test 4 scenarios:-

1. TCMU-Runner REQ_OP_ZONE_RESET :-

   Issue zone reset in reverse order and observe the zone report cmd 
   wptr. This scenario should translate into issuing N block layer
   REQ_OP_ZONE_RESET requests. On success Zone write pointer values
   should be set to 0x0 in the blkzone report command in the reverse
   order.
   (blkzone -o ${zone_start_offset} ${DEV})

2. TCMU-Runner REQ_OP_ZONE_RESET_ALL :-

   Issue zone reset with the length of the device, this should translate
   into the REQ_OP_ZONE_RESET_ALL and observe the zone report cmd wptr.
   (blkzone reset ${DEV})

3. Test for null_blk REQ_OP_ZONE_RESET :-

   Same as #1. 

4. Test for null_blk REQ_OP_ZONE_RESET_ALL :-

   Same as #2.

Chaitanya Kulkarni (4):
  block: add req op to reset all zones and flag
  blk-zoned: implement REQ_OP_ZONE_RESET_ALL
  scsi: implement REQ_OP_ZONE_RESET_ALL
  null_blk: implement REQ_OP_ZONE_RESET_ALL

 block/blk-core.c               |  5 +++++
 block/blk-zoned.c              | 40 ++++++++++++++++++++++++++++++++++
 drivers/block/null_blk_main.c  |  3 +++
 drivers/block/null_blk_zoned.c | 28 +++++++++++++++++++-----
 drivers/scsi/sd.c              |  7 +++++-
 drivers/scsi/sd.h              |  5 +++--
 drivers/scsi/sd_zbc.c          |  9 ++++++--
 include/linux/blk_types.h      |  2 ++
 include/linux/blkdev.h         |  3 +++
 9 files changed, 91 insertions(+), 11 deletions(-)


Following are the test results for the null_blk and tcmu-runner based
sd device :-

1. TCMU-Runner REQ_OP_ZONE_RESET:-

a. Populate the zones :-

# ./reset_all_test.sh /dev/sdd  
dd if=/dev/zero of=/dev/sdd bs=4096 count=1 seek=0
dd if=/dev/zero of=/dev/sdd bs=4096 count=2 seek=32768
dd if=/dev/zero of=/dev/sdd bs=4096 count=4 seek=65536
dd if=/dev/zero of=/dev/sdd bs=4096 count=8 seek=98304
dd if=/dev/zero of=/dev/sdd bs=4096 count=16 seek=131072
dd if=/dev/zero of=/dev/sdd bs=4096 count=32 seek=163840
dd if=/dev/zero of=/dev/sdd bs=4096 count=64 seek=196608
dd if=/dev/zero of=/dev/sdd bs=4096 count=128 seek=229376
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000100 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000200 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000400 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]

b. Now Issue zone reset (REQ_OP_ZONE_RESET) starting from the last zone to the
   0rth and report zones :-

Starting REQ_OP_ZONE_RESET test :- 
blkzone reset -o 1835008 /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000100 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000200 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 7 :-  REQ_OP_ZONE_RESET : Pass
---------------------------------------------------------------
blkzone reset -o 1572864 /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000100 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 6 :-  REQ_OP_ZONE_RESET : Pass
---------------------------------------------------------------
blkzone reset -o 1310720 /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 5 :-  REQ_OP_ZONE_RESET : Pass
---------------------------------------------------------------
blkzone reset -o 1048576 /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 4 :-  REQ_OP_ZONE_RESET : Pass
---------------------------------------------------------------
blkzone reset -o 786432 /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 3 :-  REQ_OP_ZONE_RESET : Pass
---------------------------------------------------------------
blkzone reset -o 524288 /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 2 :-  REQ_OP_ZONE_RESET : Pass
---------------------------------------------------------------
blkzone reset -o 262144 /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 1 :-  REQ_OP_ZONE_RESET : Pass
---------------------------------------------------------------
blkzone reset -o 0 /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 0 :-  REQ_OP_ZONE_RESET : Pass
---------------------------------------------------------------

2. TCMU-Runner REQ_OP_ZONE_RESET_ALL:-

a. Populate the zones :-

dd if=/dev/zero of=/dev/sdd bs=4096 count=1 seek=0
dd if=/dev/zero of=/dev/sdd bs=4096 count=2 seek=32768
dd if=/dev/zero of=/dev/sdd bs=4096 count=4 seek=65536
dd if=/dev/zero of=/dev/sdd bs=4096 count=8 seek=98304
dd if=/dev/zero of=/dev/sdd bs=4096 count=16 seek=131072
dd if=/dev/zero of=/dev/sdd bs=4096 count=32 seek=163840
dd if=/dev/zero of=/dev/sdd bs=4096 count=64 seek=196608
dd if=/dev/zero of=/dev/sdd bs=4096 count=128 seek=229376
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 4(cl) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000100 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000200 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000400 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
-------------------------------------------------

b. Issue REQ_OP_ZONE_RESET_ALL and report :-
blkzone reset /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
REQ_OP_ZONE_RESET_ALL : Pass
# 


3. Test for null_blk (REQ_OP_ZONE_RESET) :-

a. Load the null_blk and populate the zones :-
# modprobe null_blk zoned=1 zone_size=128 gb=1 bs=4096
# ./reset_all_test.sh /dev/nullb0
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=1 seek=0
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=2 seek=32768
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=4 seek=65536
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=8 seek=98304
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=16 seek=131072
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=32 seek=163840
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=64 seek=196608
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=128 seek=229376
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000100 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000200 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000400 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]

b. Now Issue zone reset (REQ_OP_ZONE_RESET) starting from the last zone to the
   0rth and report zones :-

Starting REQ_OP_ZONE_RESET test :- 
blkzone reset -o 1835008 /dev/nullb0
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000100 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000200 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 7 :- ---------------------------------------------------------------
blkzone reset -o 1572864 /dev/nullb0
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000100 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 6 :- ---------------------------------------------------------------
blkzone reset -o 1310720 /dev/nullb0
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 5 :- ---------------------------------------------------------------
blkzone reset -o 1048576 /dev/nullb0
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 4 :- ---------------------------------------------------------------
blkzone reset -o 786432 /dev/nullb0
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 3 :- ---------------------------------------------------------------
blkzone reset -o 524288 /dev/nullb0
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 2 :- ---------------------------------------------------------------
blkzone reset -o 262144 /dev/nullb0
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 1 :- ---------------------------------------------------------------
blkzone reset -o 0 /dev/nullb0
  start: 0x000000000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
ZONEID 0 :- ---------------------------------------------------------------

4. Test for null_blk (REQ_OP_ZONE_RESET_ALL) :-

a. Populate the zones :-
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=1 seek=0
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=2 seek=32768
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=4 seek=65536
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=8 seek=98304
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=16 seek=131072
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=32 seek=163840
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=64 seek=196608
dd if=/dev/zero of=/dev/nullb0 bs=4096 count=128 seek=229376
  start: 0x000000000, len 0x040000, wptr 0x000008 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000010 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000020 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000040 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000080 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000100 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000200 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000400 reset:0 non-seq:0, zcond: 2(oi) [type: 2(SEQ_WRITE_REQUIRED)]
-------------------------------------------------
b. Issue REQ_OP_ZONE_RESET_ALL and report :-
blkzone reset /dev/sdd
  start: 0x000000000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000040000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000080000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0000c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000100000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000140000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x000180000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
  start: 0x0001c0000, len 0x040000, wptr 0x000000 reset:0 non-seq:0, zcond: 1(em) [type: 2(SEQ_WRITE_REQUIRED)]
# 
-- 
2.17.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] block: add req op to reset all zones and flag
  2019-07-31 21:00 [PATCH 0/4] block: introduce REQ_OP_ZONE_RESET_ALL Chaitanya Kulkarni
@ 2019-07-31 21:00 ` Chaitanya Kulkarni
  2019-08-01  0:53   ` Damien Le Moal
  2019-07-31 21:01 ` [PATCH 2/4] blk-zoned: implement REQ_OP_ZONE_RESET_ALL Chaitanya Kulkarni
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Chaitanya Kulkarni @ 2019-07-31 21:00 UTC (permalink / raw)
  To: linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, damien.lemoal, sagi, dennisszhou,
	jthumshirn, osandov, ming.lei, tj, bvanassche, martin.petersen,
	Chaitanya Kulkarni

This patch introduces a new request operation REQ_OP_ZONE_RESET_ALL.
This is useful for the applications like mkfs where it needs to reset
all the zones present on the underlying block device. As part for this
patch we also introduce new QUEUE_FLAG_ZONE_RESETALL which indicates the
queue zone reset all capability and corresponding helper macro.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 include/linux/blk_types.h | 2 ++
 include/linux/blkdev.h    | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index feff3fe4467e..3991b580d6bd 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -282,6 +282,8 @@ enum req_opf {
 	REQ_OP_ZONE_RESET	= 6,
 	/* write the same sector many times */
 	REQ_OP_WRITE_SAME	= 7,
+	/* reset all the zone present on the device */
+	REQ_OP_ZONE_RESET_ALL	= 8,
 	/* write the zero filled sector many times */
 	REQ_OP_WRITE_ZEROES	= 9,
 
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 1ef375dafb1c..474008bffee2 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -611,6 +611,7 @@ struct request_queue {
 #define QUEUE_FLAG_SCSI_PASSTHROUGH 23	/* queue supports SCSI commands */
 #define QUEUE_FLAG_QUIESCED	24	/* queue has been quiesced */
 #define QUEUE_FLAG_PCI_P2PDMA	25	/* device supports PCI p2p requests */
+#define QUEUE_FLAG_ZONE_RESETALL 26	/* supports Zone Reset All */
 
 #define QUEUE_FLAG_MQ_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
 				 (1 << QUEUE_FLAG_SAME_COMP))
@@ -630,6 +631,8 @@ bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q);
 #define blk_queue_io_stat(q)	test_bit(QUEUE_FLAG_IO_STAT, &(q)->queue_flags)
 #define blk_queue_add_random(q)	test_bit(QUEUE_FLAG_ADD_RANDOM, &(q)->queue_flags)
 #define blk_queue_discard(q)	test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
+#define blk_queue_zone_resetall(q)	\
+	test_bit(QUEUE_FLAG_ZONE_RESETALL, &(q)->queue_flags)
 #define blk_queue_secure_erase(q) \
 	(test_bit(QUEUE_FLAG_SECERASE, &(q)->queue_flags))
 #define blk_queue_dax(q)	test_bit(QUEUE_FLAG_DAX, &(q)->queue_flags)
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/4] blk-zoned: implement REQ_OP_ZONE_RESET_ALL
  2019-07-31 21:00 [PATCH 0/4] block: introduce REQ_OP_ZONE_RESET_ALL Chaitanya Kulkarni
  2019-07-31 21:00 ` [PATCH 1/4] block: add req op to reset all zones and flag Chaitanya Kulkarni
@ 2019-07-31 21:01 ` Chaitanya Kulkarni
  2019-08-01  0:55   ` Damien Le Moal
  2019-07-31 21:01 ` [PATCH 3/4] scsi: " Chaitanya Kulkarni
  2019-07-31 21:01 ` [PATCH 4/4] null_blk: " Chaitanya Kulkarni
  3 siblings, 1 reply; 11+ messages in thread
From: Chaitanya Kulkarni @ 2019-07-31 21:01 UTC (permalink / raw)
  To: linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, damien.lemoal, sagi, dennisszhou,
	jthumshirn, osandov, ming.lei, tj, bvanassche, martin.petersen,
	Chaitanya Kulkarni

This implements REQ_OP_ZONE_RESET_ALL as a special case of the block
device zone reset operations where we just simply issue bio with the
newly introduced req op.

We issue this req op when the number of sectors is equal to the device's
partition's number of sectors and device has no partitions.

We also add support so that blk_op_str() can print the new reset-all
zone operation.

This patch also adds a generic make request check for newly
introduced REQ_OP_ZONE_RESET_ALL req_opf. We simply return error
when queue is zoned and reset-all flag is not set for
REQ_OP_ZONE_RESET_ALL.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 block/blk-core.c  |  5 +++++
 block/blk-zoned.c | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/block/blk-core.c b/block/blk-core.c
index d0cc6e14d2f0..1b53ab56228b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -129,6 +129,7 @@ static const char *const blk_op_name[] = {
 	REQ_OP_NAME(DISCARD),
 	REQ_OP_NAME(SECURE_ERASE),
 	REQ_OP_NAME(ZONE_RESET),
+	REQ_OP_NAME(ZONE_RESET_ALL),
 	REQ_OP_NAME(WRITE_SAME),
 	REQ_OP_NAME(WRITE_ZEROES),
 	REQ_OP_NAME(SCSI_IN),
@@ -931,6 +932,10 @@ generic_make_request_checks(struct bio *bio)
 		if (!blk_queue_is_zoned(q))
 			goto not_supported;
 		break;
+	case REQ_OP_ZONE_RESET_ALL:
+		if (!blk_queue_is_zoned(q) || !blk_queue_zone_resetall(q))
+			goto not_supported;
+		break;
 	case REQ_OP_WRITE_ZEROES:
 		if (!q->limits.max_write_zeroes_sectors)
 			goto not_supported;
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 6c503824ba3f..d1ed728b7464 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -202,6 +202,43 @@ int blkdev_report_zones(struct block_device *bdev, sector_t sector,
 }
 EXPORT_SYMBOL_GPL(blkdev_report_zones);
 
+/*
+ * Special case of zone reset operation to reset all zones in one command,
+ * useful for applications like mkfs.
+ */
+static int __blkdev_reset_all_zones(struct block_device *bdev, gfp_t gfp_mask)
+{
+	struct bio *bio = NULL;
+	int ret;
+
+	/* across the zones operations, don't need any sectors */
+	bio = bio_alloc(gfp_mask, 0);
+	bio_set_dev(bio, bdev);
+	bio_set_op_attrs(bio, REQ_OP_ZONE_RESET_ALL, 0);
+
+	ret = submit_bio_wait(bio);
+	bio_put(bio);
+
+	return ret;
+}
+
+static inline bool blkdev_allow_reset_all_zones(struct block_device *bdev,
+						sector_t nr_sectors)
+{
+	if (!blk_queue_zone_resetall(bdev_get_queue(bdev)))
+		return false;
+
+	if (nr_sectors != part_nr_sects_read(bdev->bd_part))
+		return false;
+	/*
+	 * REQ_OP_ZONE_RESET_ALL can be executed only if the block device is
+	 * the entire disk, that is, if the blocks device start offset is 0 and
+	 * its capacity is the same as the entire disk.
+	 */
+	return get_start_sect(bdev) == 0 &&
+	       part_nr_sects_read(bdev->bd_part) == get_capacity(bdev->bd_disk);
+}
+
 /**
  * blkdev_reset_zones - Reset zones write pointer
  * @bdev:	Target block device
@@ -235,6 +272,9 @@ int blkdev_reset_zones(struct block_device *bdev,
 		/* Out of range */
 		return -EINVAL;
 
+	if (blkdev_allow_reset_all_zones(bdev, nr_sectors))
+		return  __blkdev_reset_all_zones(bdev, gfp_mask);
+
 	/* Check alignment (handle eventual smaller last zone) */
 	zone_sectors = blk_queue_zone_sectors(q);
 	if (sector & (zone_sectors - 1))
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/4] scsi: implement REQ_OP_ZONE_RESET_ALL
  2019-07-31 21:00 [PATCH 0/4] block: introduce REQ_OP_ZONE_RESET_ALL Chaitanya Kulkarni
  2019-07-31 21:00 ` [PATCH 1/4] block: add req op to reset all zones and flag Chaitanya Kulkarni
  2019-07-31 21:01 ` [PATCH 2/4] blk-zoned: implement REQ_OP_ZONE_RESET_ALL Chaitanya Kulkarni
@ 2019-07-31 21:01 ` Chaitanya Kulkarni
  2019-08-01  1:00   ` Damien Le Moal
  2019-07-31 21:01 ` [PATCH 4/4] null_blk: " Chaitanya Kulkarni
  3 siblings, 1 reply; 11+ messages in thread
From: Chaitanya Kulkarni @ 2019-07-31 21:01 UTC (permalink / raw)
  To: linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, damien.lemoal, sagi, dennisszhou,
	jthumshirn, osandov, ming.lei, tj, bvanassche, martin.petersen,
	Chaitanya Kulkarni

This patch implements the zone reset all operation for sd_zbc.c. We add
a new boolean parameter for the sd_zbc_setup_reset_cmd() to indicate
REQ_OP_ZONE_RESET_ALL command setup. Along with that we add support in
the completion path for the zone reset all.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 drivers/scsi/sd.c     | 7 ++++++-
 drivers/scsi/sd.h     | 5 +++--
 drivers/scsi/sd_zbc.c | 9 +++++++--
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index a3406bd62391..620a6d743952 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1292,7 +1292,9 @@ static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
 	case REQ_OP_WRITE:
 		return sd_setup_read_write_cmnd(cmd);
 	case REQ_OP_ZONE_RESET:
-		return sd_zbc_setup_reset_cmnd(cmd);
+		return sd_zbc_setup_reset_cmnd(cmd, false);
+	case REQ_OP_ZONE_RESET_ALL:
+		return sd_zbc_setup_reset_cmnd(cmd, true);
 	default:
 		WARN_ON_ONCE(1);
 		return BLK_STS_NOTSUPP;
@@ -1958,6 +1960,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
 	case REQ_OP_WRITE_ZEROES:
 	case REQ_OP_WRITE_SAME:
 	case REQ_OP_ZONE_RESET:
+	case REQ_OP_ZONE_RESET_ALL:
 		if (!result) {
 			good_bytes = blk_rq_bytes(req);
 			scsi_set_resid(SCpnt, 0);
@@ -2948,6 +2951,8 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
 			 */
 			q->limits.zoned = BLK_ZONED_NONE;
 	}
+	if (q->limits.zoned != BLK_ZONED_NONE)
+		blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q);
 	if (blk_queue_is_zoned(q) && sdkp->first_scan)
 		sd_printk(KERN_NOTICE, sdkp, "Host-%s zoned block device\n",
 		      q->limits.zoned == BLK_ZONED_HM ? "managed" : "aware");
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 38c50946fc42..1eab779f812b 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -209,7 +209,7 @@ static inline int sd_is_zoned(struct scsi_disk *sdkp)
 
 extern int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buffer);
 extern void sd_zbc_print_zones(struct scsi_disk *sdkp);
-extern blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd);
+extern blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd, bool all);
 extern void sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes,
 			    struct scsi_sense_hdr *sshdr);
 extern int sd_zbc_report_zones(struct gendisk *disk, sector_t sector,
@@ -225,7 +225,8 @@ static inline int sd_zbc_read_zones(struct scsi_disk *sdkp,
 
 static inline void sd_zbc_print_zones(struct scsi_disk *sdkp) {}
 
-static inline blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd)
+static inline blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd,
+						   bool all)
 {
 	return BLK_STS_TARGET;
 }
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index db16c19e05c4..538216b9e1f4 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -209,10 +209,11 @@ static inline sector_t sd_zbc_zone_sectors(struct scsi_disk *sdkp)
 /**
  * sd_zbc_setup_reset_cmnd - Prepare a RESET WRITE POINTER scsi command.
  * @cmd: the command to setup
+ * @all: flag to prepare a RESET ALL WRITE POINTER scsi command.
  *
  * Called from sd_init_command() for a REQ_OP_ZONE_RESET request.
  */
-blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd)
+blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd, bool all)
 {
 	struct request *rq = cmd->request;
 	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
@@ -234,7 +235,10 @@ blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd)
 	memset(cmd->cmnd, 0, cmd->cmd_len);
 	cmd->cmnd[0] = ZBC_OUT;
 	cmd->cmnd[1] = ZO_RESET_WRITE_POINTER;
-	put_unaligned_be64(block, &cmd->cmnd[2]);
+	if (all)
+		cmd->cmnd[14] = 0x1;
+	else
+		put_unaligned_be64(block, &cmd->cmnd[2]);
 
 	rq->timeout = SD_TIMEOUT;
 	cmd->sc_data_direction = DMA_NONE;
@@ -261,6 +265,7 @@ void sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes,
 
 	switch (req_op(rq)) {
 	case REQ_OP_ZONE_RESET:
+	case REQ_OP_ZONE_RESET_ALL:
 
 		if (result &&
 		    sshdr->sense_key == ILLEGAL_REQUEST &&
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/4] null_blk: implement REQ_OP_ZONE_RESET_ALL
  2019-07-31 21:00 [PATCH 0/4] block: introduce REQ_OP_ZONE_RESET_ALL Chaitanya Kulkarni
                   ` (2 preceding siblings ...)
  2019-07-31 21:01 ` [PATCH 3/4] scsi: " Chaitanya Kulkarni
@ 2019-07-31 21:01 ` Chaitanya Kulkarni
  2019-08-01  1:03   ` Damien Le Moal
  3 siblings, 1 reply; 11+ messages in thread
From: Chaitanya Kulkarni @ 2019-07-31 21:01 UTC (permalink / raw)
  To: linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, damien.lemoal, sagi, dennisszhou,
	jthumshirn, osandov, ming.lei, tj, bvanassche, martin.petersen,
	Chaitanya Kulkarni

This patch implements newly introduced zone reset all operation for
null_blk driver.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 drivers/block/null_blk_main.c  |  3 +++
 drivers/block/null_blk_zoned.c | 28 ++++++++++++++++++++++------
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c
index 99328ded60d1..99c56d72ff78 100644
--- a/drivers/block/null_blk_main.c
+++ b/drivers/block/null_blk_main.c
@@ -1214,6 +1214,8 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd)
 			null_zone_write(cmd, sector, nr_sectors);
 		else if (op == REQ_OP_ZONE_RESET)
 			null_zone_reset(cmd, sector);
+		else if (op == REQ_OP_ZONE_RESET_ALL)
+			null_zone_reset(cmd, 0);
 	}
 out:
 	/* Complete IO by inline, softirq or timer */
@@ -1688,6 +1690,7 @@ static int null_add_dev(struct nullb_device *dev)
 
 		blk_queue_chunk_sectors(nullb->q, dev->zone_size_sects);
 		nullb->q->limits.zoned = BLK_ZONED_HM;
+		blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, nullb->q);
 	}
 
 	nullb->q->queuedata = nullb;
diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c
index cb28d93f2bd1..8c7f5bf81975 100644
--- a/drivers/block/null_blk_zoned.c
+++ b/drivers/block/null_blk_zoned.c
@@ -125,12 +125,28 @@ void null_zone_reset(struct nullb_cmd *cmd, sector_t sector)
 	struct nullb_device *dev = cmd->nq->dev;
 	unsigned int zno = null_zone_no(dev, sector);
 	struct blk_zone *zone = &dev->zones[zno];
+	size_t i;
+
+	switch (req_op(cmd->rq)) {
+	case REQ_OP_ZONE_RESET_ALL:
+		for (i = 0; i < dev->nr_zones; i++) {
+			if (zone[i].type == BLK_ZONE_TYPE_CONVENTIONAL)
+				continue;
+			zone[i].cond = BLK_ZONE_COND_EMPTY;
+			zone[i].wp = zone[i].start;
+		}
+		break;
+	case REQ_OP_ZONE_RESET:
+		if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) {
+			cmd->error = BLK_STS_IOERR;
+			return;
+		}
 
-	if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) {
-		cmd->error = BLK_STS_IOERR;
-		return;
+		zone->cond = BLK_ZONE_COND_EMPTY;
+		zone->wp = zone->start;
+		break;
+	default:
+		cmd->error = BLK_STS_NOTSUPP;
+		break;
 	}
-
-	zone->cond = BLK_ZONE_COND_EMPTY;
-	zone->wp = zone->start;
 }
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] block: add req op to reset all zones and flag
  2019-07-31 21:00 ` [PATCH 1/4] block: add req op to reset all zones and flag Chaitanya Kulkarni
@ 2019-08-01  0:53   ` Damien Le Moal
  0 siblings, 0 replies; 11+ messages in thread
From: Damien Le Moal @ 2019-08-01  0:53 UTC (permalink / raw)
  To: Chaitanya Kulkarni, linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, sagi, dennisszhou, jthumshirn,
	osandov, ming.lei, tj, bvanassche, martin.petersen

On 2019/08/01 6:01, Chaitanya Kulkarni wrote:
> This patch introduces a new request operation REQ_OP_ZONE_RESET_ALL.
> This is useful for the applications like mkfs where it needs to reset
> all the zones present on the underlying block device. As part for this
> patch we also introduce new QUEUE_FLAG_ZONE_RESETALL which indicates the
> queue zone reset all capability and corresponding helper macro.
> 
> Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
> ---
>  include/linux/blk_types.h | 2 ++
>  include/linux/blkdev.h    | 3 +++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
> index feff3fe4467e..3991b580d6bd 100644
> --- a/include/linux/blk_types.h
> +++ b/include/linux/blk_types.h
> @@ -282,6 +282,8 @@ enum req_opf {
>  	REQ_OP_ZONE_RESET	= 6,
>  	/* write the same sector many times */
>  	REQ_OP_WRITE_SAME	= 7,
> +	/* reset all the zone present on the device */
> +	REQ_OP_ZONE_RESET_ALL	= 8,
>  	/* write the zero filled sector many times */
>  	REQ_OP_WRITE_ZEROES	= 9,
>  
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index 1ef375dafb1c..474008bffee2 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -611,6 +611,7 @@ struct request_queue {
>  #define QUEUE_FLAG_SCSI_PASSTHROUGH 23	/* queue supports SCSI commands */
>  #define QUEUE_FLAG_QUIESCED	24	/* queue has been quiesced */
>  #define QUEUE_FLAG_PCI_P2PDMA	25	/* device supports PCI p2p requests */
> +#define QUEUE_FLAG_ZONE_RESETALL 26	/* supports Zone Reset All */
>  
>  #define QUEUE_FLAG_MQ_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
>  				 (1 << QUEUE_FLAG_SAME_COMP))
> @@ -630,6 +631,8 @@ bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q);
>  #define blk_queue_io_stat(q)	test_bit(QUEUE_FLAG_IO_STAT, &(q)->queue_flags)
>  #define blk_queue_add_random(q)	test_bit(QUEUE_FLAG_ADD_RANDOM, &(q)->queue_flags)
>  #define blk_queue_discard(q)	test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
> +#define blk_queue_zone_resetall(q)	\
> +	test_bit(QUEUE_FLAG_ZONE_RESETALL, &(q)->queue_flags)
>  #define blk_queue_secure_erase(q) \
>  	(test_bit(QUEUE_FLAG_SECERASE, &(q)->queue_flags))
>  #define blk_queue_dax(q)	test_bit(QUEUE_FLAG_DAX, &(q)->queue_flags)
> 

Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>

-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] blk-zoned: implement REQ_OP_ZONE_RESET_ALL
  2019-07-31 21:01 ` [PATCH 2/4] blk-zoned: implement REQ_OP_ZONE_RESET_ALL Chaitanya Kulkarni
@ 2019-08-01  0:55   ` Damien Le Moal
  2019-08-01  4:51     ` Chaitanya Kulkarni
  0 siblings, 1 reply; 11+ messages in thread
From: Damien Le Moal @ 2019-08-01  0:55 UTC (permalink / raw)
  To: Chaitanya Kulkarni, linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, sagi, dennisszhou, jthumshirn,
	osandov, ming.lei, tj, bvanassche, martin.petersen

On 2019/08/01 6:01, Chaitanya Kulkarni wrote:
> This implements REQ_OP_ZONE_RESET_ALL as a special case of the block
> device zone reset operations where we just simply issue bio with the
> newly introduced req op.
> 
> We issue this req op when the number of sectors is equal to the device's
> partition's number of sectors and device has no partitions.
> 
> We also add support so that blk_op_str() can print the new reset-all
> zone operation.
> 
> This patch also adds a generic make request check for newly
> introduced REQ_OP_ZONE_RESET_ALL req_opf. We simply return error
> when queue is zoned and reset-all flag is not set for
> REQ_OP_ZONE_RESET_ALL.
> 
> Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
> ---
>  block/blk-core.c  |  5 +++++
>  block/blk-zoned.c | 40 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 45 insertions(+)
> 
> diff --git a/block/blk-core.c b/block/blk-core.c
> index d0cc6e14d2f0..1b53ab56228b 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -129,6 +129,7 @@ static const char *const blk_op_name[] = {
>  	REQ_OP_NAME(DISCARD),
>  	REQ_OP_NAME(SECURE_ERASE),
>  	REQ_OP_NAME(ZONE_RESET),
> +	REQ_OP_NAME(ZONE_RESET_ALL),
>  	REQ_OP_NAME(WRITE_SAME),
>  	REQ_OP_NAME(WRITE_ZEROES),
>  	REQ_OP_NAME(SCSI_IN),
> @@ -931,6 +932,10 @@ generic_make_request_checks(struct bio *bio)
>  		if (!blk_queue_is_zoned(q))
>  			goto not_supported;
>  		break;
> +	case REQ_OP_ZONE_RESET_ALL:
> +		if (!blk_queue_is_zoned(q) || !blk_queue_zone_resetall(q))
> +			goto not_supported;
> +		break;
>  	case REQ_OP_WRITE_ZEROES:
>  		if (!q->limits.max_write_zeroes_sectors)
>  			goto not_supported;
> diff --git a/block/blk-zoned.c b/block/blk-zoned.c
> index 6c503824ba3f..d1ed728b7464 100644
> --- a/block/blk-zoned.c
> +++ b/block/blk-zoned.c
> @@ -202,6 +202,43 @@ int blkdev_report_zones(struct block_device *bdev, sector_t sector,
>  }
>  EXPORT_SYMBOL_GPL(blkdev_report_zones);
>  
> +/*
> + * Special case of zone reset operation to reset all zones in one command,
> + * useful for applications like mkfs.
> + */
> +static int __blkdev_reset_all_zones(struct block_device *bdev, gfp_t gfp_mask)
> +{
> +	struct bio *bio = NULL;

There is no need to initialize the bio to NULL here.

> +	int ret;
> +
> +	/* across the zones operations, don't need any sectors */
> +	bio = bio_alloc(gfp_mask, 0);
> +	bio_set_dev(bio, bdev);
> +	bio_set_op_attrs(bio, REQ_OP_ZONE_RESET_ALL, 0);
> +
> +	ret = submit_bio_wait(bio);
> +	bio_put(bio);
> +
> +	return ret;
> +}
> +
> +static inline bool blkdev_allow_reset_all_zones(struct block_device *bdev,
> +						sector_t nr_sectors)
> +{
> +	if (!blk_queue_zone_resetall(bdev_get_queue(bdev)))
> +		return false;
> +
> +	if (nr_sectors != part_nr_sects_read(bdev->bd_part))
> +		return false;
> +	/*
> +	 * REQ_OP_ZONE_RESET_ALL can be executed only if the block device is
> +	 * the entire disk, that is, if the blocks device start offset is 0 and
> +	 * its capacity is the same as the entire disk.
> +	 */
> +	return get_start_sect(bdev) == 0 &&
> +	       part_nr_sects_read(bdev->bd_part) == get_capacity(bdev->bd_disk);
> +}
> +
>  /**
>   * blkdev_reset_zones - Reset zones write pointer
>   * @bdev:	Target block device
> @@ -235,6 +272,9 @@ int blkdev_reset_zones(struct block_device *bdev,
>  		/* Out of range */
>  		return -EINVAL;
>  
> +	if (blkdev_allow_reset_all_zones(bdev, nr_sectors))
> +		return  __blkdev_reset_all_zones(bdev, gfp_mask);
> +
>  	/* Check alignment (handle eventual smaller last zone) */
>  	zone_sectors = blk_queue_zone_sectors(q);
>  	if (sector & (zone_sectors - 1))
> 


-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] scsi: implement REQ_OP_ZONE_RESET_ALL
  2019-07-31 21:01 ` [PATCH 3/4] scsi: " Chaitanya Kulkarni
@ 2019-08-01  1:00   ` Damien Le Moal
  0 siblings, 0 replies; 11+ messages in thread
From: Damien Le Moal @ 2019-08-01  1:00 UTC (permalink / raw)
  To: Chaitanya Kulkarni, linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, sagi, dennisszhou, jthumshirn,
	osandov, ming.lei, tj, bvanassche, martin.petersen

On 2019/08/01 6:02, Chaitanya Kulkarni wrote:
> This patch implements the zone reset all operation for sd_zbc.c. We add
> a new boolean parameter for the sd_zbc_setup_reset_cmd() to indicate
> REQ_OP_ZONE_RESET_ALL command setup. Along with that we add support in
> the completion path for the zone reset all.
> 
> Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
> ---
>  drivers/scsi/sd.c     | 7 ++++++-
>  drivers/scsi/sd.h     | 5 +++--
>  drivers/scsi/sd_zbc.c | 9 +++++++--
>  3 files changed, 16 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index a3406bd62391..620a6d743952 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -1292,7 +1292,9 @@ static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
>  	case REQ_OP_WRITE:
>  		return sd_setup_read_write_cmnd(cmd);
>  	case REQ_OP_ZONE_RESET:
> -		return sd_zbc_setup_reset_cmnd(cmd);
> +		return sd_zbc_setup_reset_cmnd(cmd, false);
> +	case REQ_OP_ZONE_RESET_ALL:
> +		return sd_zbc_setup_reset_cmnd(cmd, true);
>  	default:
>  		WARN_ON_ONCE(1);
>  		return BLK_STS_NOTSUPP;
> @@ -1958,6 +1960,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
>  	case REQ_OP_WRITE_ZEROES:
>  	case REQ_OP_WRITE_SAME:
>  	case REQ_OP_ZONE_RESET:
> +	case REQ_OP_ZONE_RESET_ALL:
>  		if (!result) {
>  			good_bytes = blk_rq_bytes(req);
>  			scsi_set_resid(SCpnt, 0);
> @@ -2948,6 +2951,8 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
>  			 */
>  			q->limits.zoned = BLK_ZONED_NONE;
>  	}
> +	if (q->limits.zoned != BLK_ZONED_NONE)
> +		blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q);

Move this into sd_zbc.c in sd_zbc_read_zones(). That avoids the "if" and keeps
things for ZBC in one place.

>  	if (blk_queue_is_zoned(q) && sdkp->first_scan)
>  		sd_printk(KERN_NOTICE, sdkp, "Host-%s zoned block device\n",
>  		      q->limits.zoned == BLK_ZONED_HM ? "managed" : "aware");
> diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
> index 38c50946fc42..1eab779f812b 100644
> --- a/drivers/scsi/sd.h
> +++ b/drivers/scsi/sd.h
> @@ -209,7 +209,7 @@ static inline int sd_is_zoned(struct scsi_disk *sdkp)
>  
>  extern int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buffer);
>  extern void sd_zbc_print_zones(struct scsi_disk *sdkp);
> -extern blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd);
> +extern blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd, bool all);
>  extern void sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes,
>  			    struct scsi_sense_hdr *sshdr);
>  extern int sd_zbc_report_zones(struct gendisk *disk, sector_t sector,
> @@ -225,7 +225,8 @@ static inline int sd_zbc_read_zones(struct scsi_disk *sdkp,
>  
>  static inline void sd_zbc_print_zones(struct scsi_disk *sdkp) {}
>  
> -static inline blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd)
> +static inline blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd,
> +						   bool all)
>  {
>  	return BLK_STS_TARGET;
>  }
> diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
> index db16c19e05c4..538216b9e1f4 100644
> --- a/drivers/scsi/sd_zbc.c
> +++ b/drivers/scsi/sd_zbc.c
> @@ -209,10 +209,11 @@ static inline sector_t sd_zbc_zone_sectors(struct scsi_disk *sdkp)
>  /**
>   * sd_zbc_setup_reset_cmnd - Prepare a RESET WRITE POINTER scsi command.
>   * @cmd: the command to setup
> + * @all: flag to prepare a RESET ALL WRITE POINTER scsi command.

There is no "RESET ALL WRITE POINTER" command. It is the same
RESET WRITE POINTER, but with the ALL bit set. So maybe change the description
of the argument to something like:

@all: Reset all zones control

>   *
>   * Called from sd_init_command() for a REQ_OP_ZONE_RESET request.
>   */
> -blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd)
> +blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd, bool all)
>  {
>  	struct request *rq = cmd->request;
>  	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
> @@ -234,7 +235,10 @@ blk_status_t sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd)
>  	memset(cmd->cmnd, 0, cmd->cmd_len);
>  	cmd->cmnd[0] = ZBC_OUT;
>  	cmd->cmnd[1] = ZO_RESET_WRITE_POINTER;
> -	put_unaligned_be64(block, &cmd->cmnd[2]);
> +	if (all)
> +		cmd->cmnd[14] = 0x1;
> +	else
> +		put_unaligned_be64(block, &cmd->cmnd[2]);
>  
>  	rq->timeout = SD_TIMEOUT;
>  	cmd->sc_data_direction = DMA_NONE;
> @@ -261,6 +265,7 @@ void sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes,
>  
>  	switch (req_op(rq)) {
>  	case REQ_OP_ZONE_RESET:
> +	case REQ_OP_ZONE_RESET_ALL:
>  
>  		if (result &&
>  		    sshdr->sense_key == ILLEGAL_REQUEST &&
> 


-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] null_blk: implement REQ_OP_ZONE_RESET_ALL
  2019-07-31 21:01 ` [PATCH 4/4] null_blk: " Chaitanya Kulkarni
@ 2019-08-01  1:03   ` Damien Le Moal
  0 siblings, 0 replies; 11+ messages in thread
From: Damien Le Moal @ 2019-08-01  1:03 UTC (permalink / raw)
  To: Chaitanya Kulkarni, linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, sagi, dennisszhou, jthumshirn,
	osandov, ming.lei, tj, bvanassche, martin.petersen

On 2019/08/01 6:02, Chaitanya Kulkarni wrote:
> This patch implements newly introduced zone reset all operation for
> null_blk driver.
> 
> Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
> ---
>  drivers/block/null_blk_main.c  |  3 +++
>  drivers/block/null_blk_zoned.c | 28 ++++++++++++++++++++++------
>  2 files changed, 25 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c
> index 99328ded60d1..99c56d72ff78 100644
> --- a/drivers/block/null_blk_main.c
> +++ b/drivers/block/null_blk_main.c
> @@ -1214,6 +1214,8 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd)
>  			null_zone_write(cmd, sector, nr_sectors);
>  		else if (op == REQ_OP_ZONE_RESET)
>  			null_zone_reset(cmd, sector);
> +		else if (op == REQ_OP_ZONE_RESET_ALL)
> +			null_zone_reset(cmd, 0);
>  	}
>  out:
>  	/* Complete IO by inline, softirq or timer */
> @@ -1688,6 +1690,7 @@ static int null_add_dev(struct nullb_device *dev)
>  
>  		blk_queue_chunk_sectors(nullb->q, dev->zone_size_sects);
>  		nullb->q->limits.zoned = BLK_ZONED_HM;
> +		blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, nullb->q);
>  	}
>  
>  	nullb->q->queuedata = nullb;
> diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c
> index cb28d93f2bd1..8c7f5bf81975 100644
> --- a/drivers/block/null_blk_zoned.c
> +++ b/drivers/block/null_blk_zoned.c
> @@ -125,12 +125,28 @@ void null_zone_reset(struct nullb_cmd *cmd, sector_t sector)
>  	struct nullb_device *dev = cmd->nq->dev;
>  	unsigned int zno = null_zone_no(dev, sector);
>  	struct blk_zone *zone = &dev->zones[zno];
> +	size_t i;
> +
> +	switch (req_op(cmd->rq)) {
> +	case REQ_OP_ZONE_RESET_ALL:
> +		for (i = 0; i < dev->nr_zones; i++) {
> +			if (zone[i].type == BLK_ZONE_TYPE_CONVENTIONAL)
> +				continue;
> +			zone[i].cond = BLK_ZONE_COND_EMPTY;
> +			zone[i].wp = zone[i].start;
> +		}
> +		break;
> +	case REQ_OP_ZONE_RESET:
> +		if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) {
> +			cmd->error = BLK_STS_IOERR;
> +			return;
> +		}
>  
> -	if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) {
> -		cmd->error = BLK_STS_IOERR;
> -		return;
> +		zone->cond = BLK_ZONE_COND_EMPTY;
> +		zone->wp = zone->start;
> +		break;
> +	default:
> +		cmd->error = BLK_STS_NOTSUPP;
> +		break;
>  	}
> -
> -	zone->cond = BLK_ZONE_COND_EMPTY;
> -	zone->wp = zone->start;
>  }
> 

Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>

-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] blk-zoned: implement REQ_OP_ZONE_RESET_ALL
  2019-08-01  0:55   ` Damien Le Moal
@ 2019-08-01  4:51     ` Chaitanya Kulkarni
  2019-08-01  8:40       ` Damien Le Moal
  0 siblings, 1 reply; 11+ messages in thread
From: Chaitanya Kulkarni @ 2019-08-01  4:51 UTC (permalink / raw)
  To: Damien Le Moal, linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, sagi, dennisszhou, jthumshirn,
	osandov, ming.lei, tj, bvanassche, martin.petersen








From: Damien Le Moal <Damien.LeMoal@wdc.com>

Sent: Wednesday, July 31, 2019 5:55 PM

To: Chaitanya Kulkarni <Chaitanya.Kulkarni@wdc.com>; linux-block@vger.kernel.org <linux-block@vger.kernel.org>; linux-scsi@vger.kernel.org <linux-scsi@vger.kernel.org>

Cc: axboe@kernel.dk <axboe@kernel.dk>; jejb@linux.ibm.com <jejb@linux.ibm.com>; dennis@kernel.org <dennis@kernel.org>; hare@suse.com <hare@suse.com>; sagi@grimberg.me <sagi@grimberg.me>; dennisszhou@gmail.com <dennisszhou@gmail.com>; jthumshirn@suse.de
 <jthumshirn@suse.de>; osandov@fb.com <osandov@fb.com>; ming.lei@redhat.com <ming.lei@redhat.com>; tj@kernel.org <tj@kernel.org>; bvanassche@acm.org <bvanassche@acm.org>; martin.petersen@oracle.com <martin.petersen@oracle.com>

Subject: Re: [PATCH 2/4] blk-zoned: implement REQ_OP_ZONE_RESET_ALL

 


On 2019/08/01 6:01, Chaitanya Kulkarni wrote:

> This implements REQ_OP_ZONE_RESET_ALL as a special case of the block

> device zone reset operations where we just simply issue bio with the

> newly introduced req op.

> 

> We issue this req op when the number of sectors is equal to the device's

> partition's number of sectors and device has no partitions.

> 

> We also add support so that blk_op_str() can print the new reset-all

> zone operation.

> 

> This patch also adds a generic make request check for newly

> introduced REQ_OP_ZONE_RESET_ALL req_opf. We simply return error

> when queue is zoned and reset-all flag is not set for

> REQ_OP_ZONE_RESET_ALL.

> 

> Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>

> ---

>  block/blk-core.c  |  5 +++++

>  block/blk-zoned.c | 40 ++++++++++++++++++++++++++++++++++++++++

>  2 files changed, 45 insertions(+)

> 

> diff --git a/block/blk-core.c b/block/blk-core.c

> index d0cc6e14d2f0..1b53ab56228b 100644

> --- a/block/blk-core.c

> +++ b/block/blk-core.c

> @@ -129,6 +129,7 @@ static const char *const blk_op_name[] = {

>        REQ_OP_NAME(DISCARD),

>        REQ_OP_NAME(SECURE_ERASE),

>        REQ_OP_NAME(ZONE_RESET),

> +     REQ_OP_NAME(ZONE_RESET_ALL),

>        REQ_OP_NAME(WRITE_SAME),

>        REQ_OP_NAME(WRITE_ZEROES),

>        REQ_OP_NAME(SCSI_IN),

> @@ -931,6 +932,10 @@ generic_make_request_checks(struct bio *bio)

>                if (!blk_queue_is_zoned(q))

>                        goto not_supported;

>                break;

> +     case REQ_OP_ZONE_RESET_ALL:

> +             if (!blk_queue_is_zoned(q) || !blk_queue_zone_resetall(q))

> +                     goto not_supported;

> +             break;

>        case REQ_OP_WRITE_ZEROES:

>                if (!q->limits.max_write_zeroes_sectors)

>                        goto not_supported;

> diff --git a/block/blk-zoned.c b/block/blk-zoned.c

> index 6c503824ba3f..d1ed728b7464 100644

> --- a/block/blk-zoned.c

> +++ b/block/blk-zoned.c

> @@ -202,6 +202,43 @@ int blkdev_report_zones(struct block_device *bdev, sector_t sector,

>  }

>  EXPORT_SYMBOL_GPL(blkdev_report_zones);


> +/*

> + * Special case of zone reset operation to reset all zones in one command,

> + * useful for applications like mkfs.

> + */

> +static int __blkdev_reset_all_zones(struct block_device *bdev, gfp_t gfp_mask)

> +{

> +     struct bio *bio = NULL;



There is no need to initialize the bio to NULL here.

[CK] Would you prefer something like following that declares and allocate
in one line which is similar in blk-lib.c:-blk_next_bio() function ? or we should keep
declaration and allocation on the different line :-
/*
 * Special case of zone reset operation to reset all zones in one command,
 * useful for applications like mkfs.
 */
static int __blkdev_reset_all_zones(struct block_device *bdev, gfp_t gfp_mask)
{
        struct bio *bio = bio_alloc(gfp_mask, 0); 
        int ret;                                                                                                                                           

        /* across the zones operations, don't need any sectors */
        bio_set_dev(bio, bdev);
        bio_set_op_attrs(bio, REQ_OP_ZONE_RESET_ALL, 0); 

        ret = submit_bio_wait(bio);
        bio_put(bio);

        return ret;
}



> +     int ret;

> +

> +     /* across the zones operations, don't need any sectors */

> +     bio = bio_alloc(gfp_mask, 0);

> +     bio_set_dev(bio, bdev);

> +     bio_set_op_attrs(bio, REQ_OP_ZONE_RESET_ALL, 0);

> +

> +     ret = submit_bio_wait(bio);

> +     bio_put(bio);

> +

> +     return ret;

> +}

> +

> +static inline bool blkdev_allow_reset_all_zones(struct block_device *bdev,

> +                                             sector_t nr_sectors)

> +{

> +     if (!blk_queue_zone_resetall(bdev_get_queue(bdev)))

> +             return false;

> +

> +     if (nr_sectors != part_nr_sects_read(bdev->bd_part))

> +             return false;

> +     /*

> +      * REQ_OP_ZONE_RESET_ALL can be executed only if the block device is

> +      * the entire disk, that is, if the blocks device start offset is 0 and

> +      * its capacity is the same as the entire disk.

> +      */

> +     return get_start_sect(bdev) == 0 &&

> +            part_nr_sects_read(bdev->bd_part) == get_capacity(bdev->bd_disk);

> +}

> +

>  /**

>   * blkdev_reset_zones - Reset zones write pointer

>   * @bdev:    Target block device

> @@ -235,6 +272,9 @@ int blkdev_reset_zones(struct block_device *bdev,

>                /* Out of range */

>                return -EINVAL;


> +     if (blkdev_allow_reset_all_zones(bdev, nr_sectors))

> +             return  __blkdev_reset_all_zones(bdev, gfp_mask);

> +

>        /* Check alignment (handle eventual smaller last zone) */

>        zone_sectors = blk_queue_zone_sectors(q);

>        if (sector & (zone_sectors - 1))

> 





-- 

Damien Le Moal

Western Digital Research


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] blk-zoned: implement REQ_OP_ZONE_RESET_ALL
  2019-08-01  4:51     ` Chaitanya Kulkarni
@ 2019-08-01  8:40       ` Damien Le Moal
  0 siblings, 0 replies; 11+ messages in thread
From: Damien Le Moal @ 2019-08-01  8:40 UTC (permalink / raw)
  To: Chaitanya Kulkarni, linux-block, linux-scsi
  Cc: axboe, jejb, dennis, hare, sagi, dennisszhou, jthumshirn,
	osandov, ming.lei, tj, bvanassche, martin.petersen

On 2019/08/01 13:51, Chaitanya Kulkarni wrote:>>> +/*
>>> + * Special case of zone reset operation to reset all zones in one command,
>>> + * useful for applications like mkfs.
>>> + */
>>> +static int __blkdev_reset_all_zones(struct block_device *bdev, gfp_t gfp_mask)
>>> +{
>>> +     struct bio *bio = NULL;
>> 
>> There is no need to initialize the bio to NULL here.
> 
> [CK] Would you prefer something like following that declares and allocate in
> one line which is similar in blk-lib.c:-blk_next_bio() function ? or we
> should keep declaration and allocation on the different line :-

Whichever is fine with me.

> /*
>  * Special case of zone reset operation to reset all zones in one command,
>  * useful for applications like mkfs.
>  */
> static int __blkdev_reset_all_zones(struct block_device *bdev, gfp_t gfp_mask)
> {
>         struct bio *bio = bio_alloc(gfp_mask, 0); 
>         int ret;                                                                                                                                           
> 
>         /* across the zones operations, don't need any sectors */

May be change this comment to something less cryptic, e.g.:

/* For REQ_OP_ZONE_RESET_ALL, BIO sector and size are not needed  */

>         bio_set_dev(bio, bdev);
>         bio_set_op_attrs(bio, REQ_OP_ZONE_RESET_ALL, 0); 
> 
>         ret = submit_bio_wait(bio);
>         bio_put(bio);
> 
>         return ret;
> }

-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-08-01  8:40 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-31 21:00 [PATCH 0/4] block: introduce REQ_OP_ZONE_RESET_ALL Chaitanya Kulkarni
2019-07-31 21:00 ` [PATCH 1/4] block: add req op to reset all zones and flag Chaitanya Kulkarni
2019-08-01  0:53   ` Damien Le Moal
2019-07-31 21:01 ` [PATCH 2/4] blk-zoned: implement REQ_OP_ZONE_RESET_ALL Chaitanya Kulkarni
2019-08-01  0:55   ` Damien Le Moal
2019-08-01  4:51     ` Chaitanya Kulkarni
2019-08-01  8:40       ` Damien Le Moal
2019-07-31 21:01 ` [PATCH 3/4] scsi: " Chaitanya Kulkarni
2019-08-01  1:00   ` Damien Le Moal
2019-07-31 21:01 ` [PATCH 4/4] null_blk: " Chaitanya Kulkarni
2019-08-01  1:03   ` Damien Le Moal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.