Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'block-5.14-2021-08-20' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
"Three fixes from Ming Lei that should go into 5.14:

- Fix for a kernel panic when iterating over tags for some cases
where a flush request is present, a regression in this cycle.

- Request timeout fix

- Fix flush request checking"

* tag 'block-5.14-2021-08-20' of git://git.kernel.dk/linux-block:
blk-mq: fix is_flush_rq
blk-mq: fix kernel panic during iterating over flush request
blk-mq: don't grab rq's refcount in blk_mq_check_expired()

+20 -32
-1
block/blk-core.c
··· 122 122 rq->internal_tag = BLK_MQ_NO_TAG; 123 123 rq->start_time_ns = ktime_get_ns(); 124 124 rq->part = NULL; 125 - refcount_set(&rq->ref, 1); 126 125 blk_crypto_rq_set_defaults(rq); 127 126 } 128 127 EXPORT_SYMBOL(blk_rq_init);
+13
block/blk-flush.c
··· 262 262 spin_unlock_irqrestore(&fq->mq_flush_lock, flags); 263 263 } 264 264 265 + bool is_flush_rq(struct request *rq) 266 + { 267 + return rq->end_io == flush_end_io; 268 + } 269 + 265 270 /** 266 271 * blk_kick_flush - consider issuing flush request 267 272 * @q: request_queue being kicked ··· 334 329 flush_rq->rq_flags |= RQF_FLUSH_SEQ; 335 330 flush_rq->rq_disk = first_rq->rq_disk; 336 331 flush_rq->end_io = flush_end_io; 332 + /* 333 + * Order WRITE ->end_io and WRITE rq->ref, and its pair is the one 334 + * implied in refcount_inc_not_zero() called from 335 + * blk_mq_find_and_get_req(), which orders WRITE/READ flush_rq->ref 336 + * and READ flush_rq->end_io 337 + */ 338 + smp_wmb(); 339 + refcount_set(&flush_rq->ref, 1); 337 340 338 341 blk_flush_queue_rq(flush_rq, false); 339 342 }
+6 -26
block/blk-mq.c
··· 911 911 912 912 void blk_mq_put_rq_ref(struct request *rq) 913 913 { 914 - if (is_flush_rq(rq, rq->mq_hctx)) 914 + if (is_flush_rq(rq)) 915 915 rq->end_io(rq, 0); 916 916 else if (refcount_dec_and_test(&rq->ref)) 917 917 __blk_mq_free_request(rq); ··· 923 923 unsigned long *next = priv; 924 924 925 925 /* 926 - * Just do a quick check if it is expired before locking the request in 927 - * so we're not unnecessarilly synchronizing across CPUs. 928 - */ 929 - if (!blk_mq_req_expired(rq, next)) 930 - return true; 931 - 932 - /* 933 - * We have reason to believe the request may be expired. Take a 934 - * reference on the request to lock this request lifetime into its 935 - * currently allocated context to prevent it from being reallocated in 936 - * the event the completion by-passes this timeout handler. 937 - * 938 - * If the reference was already released, then the driver beat the 939 - * timeout handler to posting a natural completion. 940 - */ 941 - if (!refcount_inc_not_zero(&rq->ref)) 942 - return true; 943 - 944 - /* 945 - * The request is now locked and cannot be reallocated underneath the 946 - * timeout handler's processing. Re-verify this exact request is truly 947 - * expired; if it is not expired, then the request was completed and 948 - * reallocated as a new request. 926 + * blk_mq_queue_tag_busy_iter() has locked the request, so it cannot 927 + * be reallocated underneath the timeout handler's processing, then 928 + * the expire check is reliable. If the request is not expired, then 929 + * it was completed and reallocated as a new request after returning 930 + * from blk_mq_check_expired(). 949 931 */ 950 932 if (blk_mq_req_expired(rq, next)) 951 933 blk_mq_rq_timed_out(rq, reserved); 952 - 953 - blk_mq_put_rq_ref(rq); 954 934 return true; 955 935 } 956 936
+1 -5
block/blk.h
··· 44 44 kobject_get(&q->kobj); 45 45 } 46 46 47 - static inline bool 48 - is_flush_rq(struct request *req, struct blk_mq_hw_ctx *hctx) 49 - { 50 - return hctx->fq->flush_rq == req; 51 - } 47 + bool is_flush_rq(struct request *req); 52 48 53 49 struct blk_flush_queue *blk_alloc_flush_queue(int node, int cmd_size, 54 50 gfp_t flags);