@@ -730,7 +730,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
730730 * If not tell the caller that it should skip this queue.
731731 */
732732 ret = - EXDEV ;
733- data .hctx = xa_load ( & q -> hctx_table , hctx_idx ) ;
733+ data .hctx = q -> queue_hw_ctx [ hctx_idx ] ;
734734 if (!blk_mq_hw_queue_mapped (data .hctx ))
735735 goto out_queue_exit ;
736736 cpu = cpumask_first_and (data .hctx -> cpumask , cpu_online_mask );
@@ -3946,8 +3946,6 @@ static void blk_mq_exit_hctx(struct request_queue *q,
39463946 blk_free_flush_queue_callback );
39473947 hctx -> fq = NULL ;
39483948
3949- xa_erase (& q -> hctx_table , hctx_idx );
3950-
39513949 spin_lock (& q -> unused_hctx_lock );
39523950 list_add (& hctx -> hctx_list , & q -> unused_hctx_list );
39533951 spin_unlock (& q -> unused_hctx_lock );
@@ -3989,14 +3987,8 @@ static int blk_mq_init_hctx(struct request_queue *q,
39893987 hctx -> numa_node ))
39903988 goto exit_hctx ;
39913989
3992- if (xa_insert (& q -> hctx_table , hctx_idx , hctx , GFP_KERNEL ))
3993- goto exit_flush_rq ;
3994-
39953990 return 0 ;
39963991
3997- exit_flush_rq :
3998- if (set -> ops -> exit_request )
3999- set -> ops -> exit_request (set , hctx -> fq -> flush_rq , hctx_idx );
40003992 exit_hctx :
40013993 if (set -> ops -> exit_hctx )
40023994 set -> ops -> exit_hctx (hctx , hctx_idx );
@@ -4385,7 +4377,7 @@ void blk_mq_release(struct request_queue *q)
43854377 kobject_put (& hctx -> kobj );
43864378 }
43874379
4388- xa_destroy ( & q -> hctx_table );
4380+ kfree ( q -> queue_hw_ctx );
43894381
43904382 /*
43914383 * release .mq_kobj and sw queue's kobject now because
@@ -4529,26 +4521,44 @@ static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
45294521static void __blk_mq_realloc_hw_ctxs (struct blk_mq_tag_set * set ,
45304522 struct request_queue * q )
45314523{
4532- struct blk_mq_hw_ctx * hctx ;
4533- unsigned long i , j ;
4524+ int i , j , end ;
4525+ struct blk_mq_hw_ctx * * hctxs = q -> queue_hw_ctx ;
4526+
4527+ if (q -> nr_hw_queues < set -> nr_hw_queues ) {
4528+ struct blk_mq_hw_ctx * * new_hctxs ;
4529+
4530+ new_hctxs = kcalloc_node (set -> nr_hw_queues ,
4531+ sizeof (* new_hctxs ), GFP_KERNEL ,
4532+ set -> numa_node );
4533+ if (!new_hctxs )
4534+ return ;
4535+ if (hctxs )
4536+ memcpy (new_hctxs , hctxs , q -> nr_hw_queues *
4537+ sizeof (* hctxs ));
4538+ q -> queue_hw_ctx = new_hctxs ;
4539+ kfree (hctxs );
4540+ hctxs = new_hctxs ;
4541+ }
45344542
45354543 for (i = 0 ; i < set -> nr_hw_queues ; i ++ ) {
45364544 int old_node ;
45374545 int node = blk_mq_get_hctx_node (set , i );
4538- struct blk_mq_hw_ctx * old_hctx = xa_load ( & q -> hctx_table , i ) ;
4546+ struct blk_mq_hw_ctx * old_hctx = hctxs [ i ] ;
45394547
45404548 if (old_hctx ) {
45414549 old_node = old_hctx -> numa_node ;
45424550 blk_mq_exit_hctx (q , set , old_hctx , i );
45434551 }
45444552
4545- if (!blk_mq_alloc_and_init_hctx (set , q , i , node )) {
4553+ hctxs [i ] = blk_mq_alloc_and_init_hctx (set , q , i , node );
4554+ if (!hctxs [i ]) {
45464555 if (!old_hctx )
45474556 break ;
45484557 pr_warn ("Allocate new hctx on node %d fails, fallback to previous one on node %d\n" ,
45494558 node , old_node );
4550- hctx = blk_mq_alloc_and_init_hctx (set , q , i , old_node );
4551- WARN_ON_ONCE (!hctx );
4559+ hctxs [i ] = blk_mq_alloc_and_init_hctx (set , q , i ,
4560+ old_node );
4561+ WARN_ON_ONCE (!hctxs [i ]);
45524562 }
45534563 }
45544564 /*
@@ -4557,13 +4567,21 @@ static void __blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
45574567 */
45584568 if (i != set -> nr_hw_queues ) {
45594569 j = q -> nr_hw_queues ;
4570+ end = i ;
45604571 } else {
45614572 j = i ;
4573+ end = q -> nr_hw_queues ;
45624574 q -> nr_hw_queues = set -> nr_hw_queues ;
45634575 }
45644576
4565- xa_for_each_start (& q -> hctx_table , j , hctx , j )
4566- blk_mq_exit_hctx (q , set , hctx , j );
4577+ for (; j < end ; j ++ ) {
4578+ struct blk_mq_hw_ctx * hctx = hctxs [j ];
4579+
4580+ if (hctx ) {
4581+ blk_mq_exit_hctx (q , set , hctx , j );
4582+ hctxs [j ] = NULL ;
4583+ }
4584+ }
45674585}
45684586
45694587static void blk_mq_realloc_hw_ctxs (struct blk_mq_tag_set * set ,
@@ -4599,8 +4617,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
45994617 INIT_LIST_HEAD (& q -> unused_hctx_list );
46004618 spin_lock_init (& q -> unused_hctx_lock );
46014619
4602- xa_init (& q -> hctx_table );
4603-
46044620 blk_mq_realloc_hw_ctxs (set , q );
46054621 if (!q -> nr_hw_queues )
46064622 goto err_hctxs ;
@@ -5187,7 +5203,7 @@ int blk_mq_poll(struct request_queue *q, blk_qc_t cookie,
51875203{
51885204 if (!blk_mq_can_poll (q ))
51895205 return 0 ;
5190- return blk_hctx_poll (q , xa_load ( & q -> hctx_table , cookie ) , iob , flags );
5206+ return blk_hctx_poll (q , q -> queue_hw_ctx [ cookie ] , iob , flags );
51915207}
51925208
51935209int blk_rq_poll (struct request * rq , struct io_comp_batch * iob ,
0 commit comments