Skip to content

Commit 9327b51

Browse files
Ming Leiaxboe
authored andcommitted
ublk: move zone report data out of request pdu
ublk zoned takes 16 bytes in each request pdu just for handling REPORT_ZONE operation, this way does waste memory since request pdu is allocated statically. Store the transient zone report data into one global xarray, and remove it after the report zone request is completed. This way is reasonable since report zone is run in slow code path. Fixes: 29802d7 ("ublk: enable zoned storage support") Cc: Damien Le Moal <[email protected]> Cc: Andreas Hindborg <[email protected]> Signed-off-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent f48ada4 commit 9327b51

File tree

1 file changed

+46
-16
lines changed

1 file changed

+46
-16
lines changed

drivers/block/ublk_drv.c

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@ struct ublk_rq_data {
7171
struct llist_node node;
7272

7373
struct kref ref;
74-
__u64 sector;
75-
__u32 operation;
76-
__u32 nr_zones;
7774
};
7875

7976
struct ublk_uring_cmd_pdu {
@@ -214,6 +211,33 @@ static inline bool ublk_queue_is_zoned(struct ublk_queue *ubq)
214211

215212
#ifdef CONFIG_BLK_DEV_ZONED
216213

214+
struct ublk_zoned_report_desc {
215+
__u64 sector;
216+
__u32 operation;
217+
__u32 nr_zones;
218+
};
219+
220+
static DEFINE_XARRAY(ublk_zoned_report_descs);
221+
222+
static int ublk_zoned_insert_report_desc(const struct request *req,
223+
struct ublk_zoned_report_desc *desc)
224+
{
225+
return xa_insert(&ublk_zoned_report_descs, (unsigned long)req,
226+
desc, GFP_KERNEL);
227+
}
228+
229+
static struct ublk_zoned_report_desc *ublk_zoned_erase_report_desc(
230+
const struct request *req)
231+
{
232+
return xa_erase(&ublk_zoned_report_descs, (unsigned long)req);
233+
}
234+
235+
static struct ublk_zoned_report_desc *ublk_zoned_get_report_desc(
236+
const struct request *req)
237+
{
238+
return xa_load(&ublk_zoned_report_descs, (unsigned long)req);
239+
}
240+
217241
static int ublk_get_nr_zones(const struct ublk_device *ub)
218242
{
219243
const struct ublk_param_basic *p = &ub->params.basic;
@@ -308,7 +332,7 @@ static int ublk_report_zones(struct gendisk *disk, sector_t sector,
308332
unsigned int zones_in_request =
309333
min_t(unsigned int, remaining_zones, max_zones_per_request);
310334
struct request *req;
311-
struct ublk_rq_data *pdu;
335+
struct ublk_zoned_report_desc desc;
312336
blk_status_t status;
313337

314338
memset(buffer, 0, buffer_length);
@@ -319,20 +343,23 @@ static int ublk_report_zones(struct gendisk *disk, sector_t sector,
319343
goto out;
320344
}
321345

322-
pdu = blk_mq_rq_to_pdu(req);
323-
pdu->operation = UBLK_IO_OP_REPORT_ZONES;
324-
pdu->sector = sector;
325-
pdu->nr_zones = zones_in_request;
346+
desc.operation = UBLK_IO_OP_REPORT_ZONES;
347+
desc.sector = sector;
348+
desc.nr_zones = zones_in_request;
349+
ret = ublk_zoned_insert_report_desc(req, &desc);
350+
if (ret)
351+
goto free_req;
326352

327353
ret = blk_rq_map_kern(disk->queue, req, buffer, buffer_length,
328354
GFP_KERNEL);
329-
if (ret) {
330-
blk_mq_free_request(req);
331-
goto out;
332-
}
355+
if (ret)
356+
goto erase_desc;
333357

334358
status = blk_execute_rq(req, 0);
335359
ret = blk_status_to_errno(status);
360+
erase_desc:
361+
ublk_zoned_erase_report_desc(req);
362+
free_req:
336363
blk_mq_free_request(req);
337364
if (ret)
338365
goto out;
@@ -366,7 +393,7 @@ static blk_status_t ublk_setup_iod_zoned(struct ublk_queue *ubq,
366393
{
367394
struct ublksrv_io_desc *iod = ublk_get_iod(ubq, req->tag);
368395
struct ublk_io *io = &ubq->ios[req->tag];
369-
struct ublk_rq_data *pdu = blk_mq_rq_to_pdu(req);
396+
struct ublk_zoned_report_desc *desc;
370397
u32 ublk_op;
371398

372399
switch (req_op(req)) {
@@ -389,12 +416,15 @@ static blk_status_t ublk_setup_iod_zoned(struct ublk_queue *ubq,
389416
ublk_op = UBLK_IO_OP_ZONE_RESET_ALL;
390417
break;
391418
case REQ_OP_DRV_IN:
392-
ublk_op = pdu->operation;
419+
desc = ublk_zoned_get_report_desc(req);
420+
if (!desc)
421+
return BLK_STS_IOERR;
422+
ublk_op = desc->operation;
393423
switch (ublk_op) {
394424
case UBLK_IO_OP_REPORT_ZONES:
395425
iod->op_flags = ublk_op | ublk_req_build_flags(req);
396-
iod->nr_zones = pdu->nr_zones;
397-
iod->start_sector = pdu->sector;
426+
iod->nr_zones = desc->nr_zones;
427+
iod->start_sector = desc->sector;
398428
return BLK_STS_OK;
399429
default:
400430
return BLK_STS_IOERR;

0 commit comments

Comments
 (0)