Skip to content

Commit 75a5e59

Browse files
Ming Leigregkh
authored andcommitted
ublk: move zone report data out of request pdu
[ Upstream commit 9327b51 ] 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]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 0ceb2f2 commit 75a5e59

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
@@ -68,9 +68,6 @@ struct ublk_rq_data {
6868
struct llist_node node;
6969

7070
struct kref ref;
71-
__u64 sector;
72-
__u32 operation;
73-
__u32 nr_zones;
7471
};
7572

7673
struct ublk_uring_cmd_pdu {
@@ -215,6 +212,33 @@ static inline bool ublk_queue_is_zoned(struct ublk_queue *ubq)
215212

216213
#ifdef CONFIG_BLK_DEV_ZONED
217214

215+
struct ublk_zoned_report_desc {
216+
__u64 sector;
217+
__u32 operation;
218+
__u32 nr_zones;
219+
};
220+
221+
static DEFINE_XARRAY(ublk_zoned_report_descs);
222+
223+
static int ublk_zoned_insert_report_desc(const struct request *req,
224+
struct ublk_zoned_report_desc *desc)
225+
{
226+
return xa_insert(&ublk_zoned_report_descs, (unsigned long)req,
227+
desc, GFP_KERNEL);
228+
}
229+
230+
static struct ublk_zoned_report_desc *ublk_zoned_erase_report_desc(
231+
const struct request *req)
232+
{
233+
return xa_erase(&ublk_zoned_report_descs, (unsigned long)req);
234+
}
235+
236+
static struct ublk_zoned_report_desc *ublk_zoned_get_report_desc(
237+
const struct request *req)
238+
{
239+
return xa_load(&ublk_zoned_report_descs, (unsigned long)req);
240+
}
241+
218242
static int ublk_get_nr_zones(const struct ublk_device *ub)
219243
{
220244
const struct ublk_param_basic *p = &ub->params.basic;
@@ -321,7 +345,7 @@ static int ublk_report_zones(struct gendisk *disk, sector_t sector,
321345
unsigned int zones_in_request =
322346
min_t(unsigned int, remaining_zones, max_zones_per_request);
323347
struct request *req;
324-
struct ublk_rq_data *pdu;
348+
struct ublk_zoned_report_desc desc;
325349
blk_status_t status;
326350

327351
memset(buffer, 0, buffer_length);
@@ -332,20 +356,23 @@ static int ublk_report_zones(struct gendisk *disk, sector_t sector,
332356
goto out;
333357
}
334358

335-
pdu = blk_mq_rq_to_pdu(req);
336-
pdu->operation = UBLK_IO_OP_REPORT_ZONES;
337-
pdu->sector = sector;
338-
pdu->nr_zones = zones_in_request;
359+
desc.operation = UBLK_IO_OP_REPORT_ZONES;
360+
desc.sector = sector;
361+
desc.nr_zones = zones_in_request;
362+
ret = ublk_zoned_insert_report_desc(req, &desc);
363+
if (ret)
364+
goto free_req;
339365

340366
ret = blk_rq_map_kern(disk->queue, req, buffer, buffer_length,
341367
GFP_KERNEL);
342-
if (ret) {
343-
blk_mq_free_request(req);
344-
goto out;
345-
}
368+
if (ret)
369+
goto erase_desc;
346370

347371
status = blk_execute_rq(req, 0);
348372
ret = blk_status_to_errno(status);
373+
erase_desc:
374+
ublk_zoned_erase_report_desc(req);
375+
free_req:
349376
blk_mq_free_request(req);
350377
if (ret)
351378
goto out;
@@ -379,7 +406,7 @@ static blk_status_t ublk_setup_iod_zoned(struct ublk_queue *ubq,
379406
{
380407
struct ublksrv_io_desc *iod = ublk_get_iod(ubq, req->tag);
381408
struct ublk_io *io = &ubq->ios[req->tag];
382-
struct ublk_rq_data *pdu = blk_mq_rq_to_pdu(req);
409+
struct ublk_zoned_report_desc *desc;
383410
u32 ublk_op;
384411

385412
switch (req_op(req)) {
@@ -402,12 +429,15 @@ static blk_status_t ublk_setup_iod_zoned(struct ublk_queue *ubq,
402429
ublk_op = UBLK_IO_OP_ZONE_RESET_ALL;
403430
break;
404431
case REQ_OP_DRV_IN:
405-
ublk_op = pdu->operation;
432+
desc = ublk_zoned_get_report_desc(req);
433+
if (!desc)
434+
return BLK_STS_IOERR;
435+
ublk_op = desc->operation;
406436
switch (ublk_op) {
407437
case UBLK_IO_OP_REPORT_ZONES:
408438
iod->op_flags = ublk_op | ublk_req_build_flags(req);
409-
iod->nr_zones = pdu->nr_zones;
410-
iod->start_sector = pdu->sector;
439+
iod->nr_zones = desc->nr_zones;
440+
iod->start_sector = desc->sector;
411441
return BLK_STS_OK;
412442
default:
413443
return BLK_STS_IOERR;

0 commit comments

Comments
 (0)