Skip to content

Commit 9236c5f

Browse files
damien-lemoalaxboe
authored andcommitted
zloop: introduce the zone_append configuration parameter
A zloop zoned block device declares to the block layer that it supports zone append operations. That is, a zloop device ressembles an NVMe ZNS devices supporting zone append. This native support is fine but it does not allow exercising the block layer zone write plugging emulation of zone append, as is done with SCSI or ATA SMR HDDs. Introduce the zone_append configuration parameter to allow creating a zloop device without native support for zone append, thus relying on the block layer zone append emulation. If not specified, zone append support is enabled by default. Otherwise, a value of 0 disables native zone append and a value of 1 enables it. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent e3a96ca commit 9236c5f

1 file changed

Lines changed: 30 additions & 2 deletions

File tree

drivers/block/zloop.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ enum {
3232
ZLOOP_OPT_NR_QUEUES = (1 << 6),
3333
ZLOOP_OPT_QUEUE_DEPTH = (1 << 7),
3434
ZLOOP_OPT_BUFFERED_IO = (1 << 8),
35+
ZLOOP_OPT_ZONE_APPEND = (1 << 9),
3536
};
3637

3738
static const match_table_t zloop_opt_tokens = {
@@ -44,6 +45,7 @@ static const match_table_t zloop_opt_tokens = {
4445
{ ZLOOP_OPT_NR_QUEUES, "nr_queues=%u" },
4546
{ ZLOOP_OPT_QUEUE_DEPTH, "queue_depth=%u" },
4647
{ ZLOOP_OPT_BUFFERED_IO, "buffered_io" },
48+
{ ZLOOP_OPT_ZONE_APPEND, "zone_append=%u" },
4749
{ ZLOOP_OPT_ERR, NULL }
4850
};
4951

@@ -56,6 +58,7 @@ static const match_table_t zloop_opt_tokens = {
5658
#define ZLOOP_DEF_NR_QUEUES 1
5759
#define ZLOOP_DEF_QUEUE_DEPTH 128
5860
#define ZLOOP_DEF_BUFFERED_IO false
61+
#define ZLOOP_DEF_ZONE_APPEND true
5962

6063
/* Arbitrary limit on the zone size (16GB). */
6164
#define ZLOOP_MAX_ZONE_SIZE_MB 16384
@@ -71,6 +74,7 @@ struct zloop_options {
7174
unsigned int nr_queues;
7275
unsigned int queue_depth;
7376
bool buffered_io;
77+
bool zone_append;
7478
};
7579

7680
/*
@@ -108,6 +112,7 @@ struct zloop_device {
108112

109113
struct workqueue_struct *workqueue;
110114
bool buffered_io;
115+
bool zone_append;
111116

112117
const char *base_dir;
113118
struct file *data_dir;
@@ -378,6 +383,11 @@ static void zloop_rw(struct zloop_cmd *cmd)
378383
cmd->nr_sectors = nr_sectors;
379384
cmd->ret = 0;
380385

386+
if (WARN_ON_ONCE(is_append && !zlo->zone_append)) {
387+
ret = -EIO;
388+
goto out;
389+
}
390+
381391
/* We should never get an I/O beyond the device capacity. */
382392
if (WARN_ON_ONCE(zone_no >= zlo->nr_zones)) {
383393
ret = -EIO;
@@ -889,7 +899,6 @@ static int zloop_ctl_add(struct zloop_options *opts)
889899
{
890900
struct queue_limits lim = {
891901
.max_hw_sectors = SZ_1M >> SECTOR_SHIFT,
892-
.max_hw_zone_append_sectors = SZ_1M >> SECTOR_SHIFT,
893902
.chunk_sectors = opts->zone_size,
894903
.features = BLK_FEAT_ZONED,
895904
};
@@ -941,6 +950,7 @@ static int zloop_ctl_add(struct zloop_options *opts)
941950
zlo->nr_zones = nr_zones;
942951
zlo->nr_conv_zones = opts->nr_conv_zones;
943952
zlo->buffered_io = opts->buffered_io;
953+
zlo->zone_append = opts->zone_append;
944954

945955
zlo->workqueue = alloc_workqueue("zloop%d", WQ_UNBOUND | WQ_FREEZABLE,
946956
opts->nr_queues * opts->queue_depth, zlo->id);
@@ -981,6 +991,8 @@ static int zloop_ctl_add(struct zloop_options *opts)
981991

982992
lim.physical_block_size = zlo->block_size;
983993
lim.logical_block_size = zlo->block_size;
994+
if (zlo->zone_append)
995+
lim.max_hw_zone_append_sectors = lim.max_hw_sectors;
984996

985997
zlo->tag_set.ops = &zloop_mq_ops;
986998
zlo->tag_set.nr_hw_queues = opts->nr_queues;
@@ -1021,10 +1033,13 @@ static int zloop_ctl_add(struct zloop_options *opts)
10211033
zlo->state = Zlo_live;
10221034
mutex_unlock(&zloop_ctl_mutex);
10231035

1024-
pr_info("Added device %d: %u zones of %llu MB, %u B block size\n",
1036+
pr_info("zloop: device %d, %u zones of %llu MiB, %u B block size\n",
10251037
zlo->id, zlo->nr_zones,
10261038
((sector_t)zlo->zone_size << SECTOR_SHIFT) >> 20,
10271039
zlo->block_size);
1040+
pr_info("zloop%d: using %s zone append\n",
1041+
zlo->id,
1042+
zlo->zone_append ? "native" : "emulated");
10281043

10291044
return 0;
10301045

@@ -1111,6 +1126,7 @@ static int zloop_parse_options(struct zloop_options *opts, const char *buf)
11111126
opts->nr_queues = ZLOOP_DEF_NR_QUEUES;
11121127
opts->queue_depth = ZLOOP_DEF_QUEUE_DEPTH;
11131128
opts->buffered_io = ZLOOP_DEF_BUFFERED_IO;
1129+
opts->zone_append = ZLOOP_DEF_ZONE_APPEND;
11141130

11151131
if (!buf)
11161132
return 0;
@@ -1220,6 +1236,18 @@ static int zloop_parse_options(struct zloop_options *opts, const char *buf)
12201236
case ZLOOP_OPT_BUFFERED_IO:
12211237
opts->buffered_io = true;
12221238
break;
1239+
case ZLOOP_OPT_ZONE_APPEND:
1240+
if (match_uint(args, &token)) {
1241+
ret = -EINVAL;
1242+
goto out;
1243+
}
1244+
if (token != 0 && token != 1) {
1245+
pr_err("Invalid zone_append value\n");
1246+
ret = -EINVAL;
1247+
goto out;
1248+
}
1249+
opts->zone_append = token;
1250+
break;
12231251
case ZLOOP_OPT_ERR:
12241252
default:
12251253
pr_warn("unknown parameter or missing value '%s'\n", p);

0 commit comments

Comments
 (0)