Skip to content

Commit 6d247d7

Browse files
Christoph Hellwigaxboe
authored andcommitted
block: allow specifying size for extra command data
This mirrors the blk-mq capabilities to allocate extra drivers-specific data behind struct request by setting a cmd_size field, as well as having a constructor / destructor for it. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Jens Axboe <axboe@fb.com>
1 parent 5ea708d commit 6d247d7

File tree

4 files changed

+61
-17
lines changed

4 files changed

+61
-17
lines changed

block/blk-core.c

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -606,17 +606,41 @@ void blk_cleanup_queue(struct request_queue *q)
606606
EXPORT_SYMBOL(blk_cleanup_queue);
607607

608608
/* Allocate memory local to the request queue */
609-
static void *alloc_request_struct(gfp_t gfp_mask, void *data)
609+
static void *alloc_request_simple(gfp_t gfp_mask, void *data)
610610
{
611-
int nid = (int)(long)data;
612-
return kmem_cache_alloc_node(request_cachep, gfp_mask, nid);
611+
struct request_queue *q = data;
612+
613+
return kmem_cache_alloc_node(request_cachep, gfp_mask, q->node);
613614
}
614615

615-
static void free_request_struct(void *element, void *unused)
616+
static void free_request_simple(void *element, void *data)
616617
{
617618
kmem_cache_free(request_cachep, element);
618619
}
619620

621+
static void *alloc_request_size(gfp_t gfp_mask, void *data)
622+
{
623+
struct request_queue *q = data;
624+
struct request *rq;
625+
626+
rq = kmalloc_node(sizeof(struct request) + q->cmd_size, gfp_mask,
627+
q->node);
628+
if (rq && q->init_rq_fn && q->init_rq_fn(q, rq, gfp_mask) < 0) {
629+
kfree(rq);
630+
rq = NULL;
631+
}
632+
return rq;
633+
}
634+
635+
static void free_request_size(void *element, void *data)
636+
{
637+
struct request_queue *q = data;
638+
639+
if (q->exit_rq_fn)
640+
q->exit_rq_fn(q, element);
641+
kfree(element);
642+
}
643+
620644
int blk_init_rl(struct request_list *rl, struct request_queue *q,
621645
gfp_t gfp_mask)
622646
{
@@ -629,10 +653,15 @@ int blk_init_rl(struct request_list *rl, struct request_queue *q,
629653
init_waitqueue_head(&rl->wait[BLK_RW_SYNC]);
630654
init_waitqueue_head(&rl->wait[BLK_RW_ASYNC]);
631655

632-
rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, alloc_request_struct,
633-
free_request_struct,
634-
(void *)(long)q->node, gfp_mask,
635-
q->node);
656+
if (q->cmd_size) {
657+
rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ,
658+
alloc_request_size, free_request_size,
659+
q, gfp_mask, q->node);
660+
} else {
661+
rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ,
662+
alloc_request_simple, free_request_simple,
663+
q, gfp_mask, q->node);
664+
}
636665
if (!rl->rq_pool)
637666
return -ENOMEM;
638667

@@ -846,12 +875,15 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio);
846875

847876
int blk_init_allocated_queue(struct request_queue *q)
848877
{
849-
q->fq = blk_alloc_flush_queue(q, NUMA_NO_NODE, 0);
878+
q->fq = blk_alloc_flush_queue(q, NUMA_NO_NODE, q->cmd_size);
850879
if (!q->fq)
851880
return -ENOMEM;
852881

882+
if (q->init_rq_fn && q->init_rq_fn(q, q->fq->flush_rq, GFP_KERNEL))
883+
goto out_free_flush_queue;
884+
853885
if (blk_init_rl(&q->root_rl, q, GFP_KERNEL))
854-
goto fail;
886+
goto out_exit_flush_rq;
855887

856888
INIT_WORK(&q->timeout_work, blk_timeout_work);
857889
q->queue_flags |= QUEUE_FLAG_DEFAULT;
@@ -869,13 +901,16 @@ int blk_init_allocated_queue(struct request_queue *q)
869901
/* init elevator */
870902
if (elevator_init(q, NULL)) {
871903
mutex_unlock(&q->sysfs_lock);
872-
goto fail;
904+
goto out_exit_flush_rq;
873905
}
874906

875907
mutex_unlock(&q->sysfs_lock);
876908
return 0;
877909

878-
fail:
910+
out_exit_flush_rq:
911+
if (q->exit_rq_fn)
912+
q->exit_rq_fn(q, q->fq->flush_rq);
913+
out_free_flush_queue:
879914
blk_free_flush_queue(q->fq);
880915
wbt_exit(q);
881916
return -ENOMEM;

block/blk-flush.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -547,11 +547,10 @@ struct blk_flush_queue *blk_alloc_flush_queue(struct request_queue *q,
547547
if (!fq)
548548
goto fail;
549549

550-
if (q->mq_ops) {
550+
if (q->mq_ops)
551551
spin_lock_init(&fq->mq_flush_lock);
552-
rq_sz = round_up(rq_sz + cmd_size, cache_line_size());
553-
}
554552

553+
rq_sz = round_up(rq_sz + cmd_size, cache_line_size());
555554
fq->flush_rq = kzalloc_node(rq_sz, GFP_KERNEL, node);
556555
if (!fq->flush_rq)
557556
goto fail_rq;

block/blk-sysfs.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,10 +814,13 @@ static void blk_release_queue(struct kobject *kobj)
814814
if (q->queue_tags)
815815
__blk_queue_free_tags(q);
816816

817-
if (!q->mq_ops)
817+
if (!q->mq_ops) {
818+
if (q->exit_rq_fn)
819+
q->exit_rq_fn(q, q->fq->flush_rq);
818820
blk_free_flush_queue(q->fq);
819-
else
821+
} else {
820822
blk_mq_release(q);
823+
}
821824

822825
blk_trace_shutdown(q);
823826

include/linux/blkdev.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ typedef void (softirq_done_fn)(struct request *);
273273
typedef int (dma_drain_needed_fn)(struct request *);
274274
typedef int (lld_busy_fn) (struct request_queue *q);
275275
typedef int (bsg_job_fn) (struct bsg_job *);
276+
typedef int (init_rq_fn)(struct request_queue *, struct request *, gfp_t);
277+
typedef void (exit_rq_fn)(struct request_queue *, struct request *);
276278

277279
enum blk_eh_timer_return {
278280
BLK_EH_NOT_HANDLED,
@@ -408,6 +410,8 @@ struct request_queue {
408410
rq_timed_out_fn *rq_timed_out_fn;
409411
dma_drain_needed_fn *dma_drain_needed;
410412
lld_busy_fn *lld_busy_fn;
413+
init_rq_fn *init_rq_fn;
414+
exit_rq_fn *exit_rq_fn;
411415

412416
const struct blk_mq_ops *mq_ops;
413417

@@ -577,6 +581,9 @@ struct request_queue {
577581
#endif
578582

579583
bool mq_sysfs_init_done;
584+
585+
size_t cmd_size;
586+
void *rq_alloc_data;
580587
};
581588

582589
#define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */

0 commit comments

Comments
 (0)