diff options
| author | Michael Bestas <mkbestas@lineageos.org> | 2020-06-04 00:49:19 +0300 |
|---|---|---|
| committer | Michael Bestas <mkbestas@lineageos.org> | 2020-06-04 00:49:19 +0300 |
| commit | 08e780103611fb2be36c17ff80de6cb54c910dd0 (patch) | |
| tree | 8bd63552a71f699da64faee819fc9c56501be6f2 /block | |
| parent | 978414b66805b23c93560db9cdacd4fd83f8cc52 (diff) | |
| parent | 60fca757270659c627384fcfe7219d2b85f1459c (diff) | |
Merge branch 'android-4.4-p' of https://android.googlesource.com/kernel/common into lineage-17.1-caf-msm8998
This brings LA.UM.8.4.r1-05500-8x98.0 up to date with
https://android.googlesource.com/kernel/common/ android-4.4-p at commit:
60fca75727065 Merge 4.4.226 into android-4.4-p
Conflicts:
drivers/base/firmware_class.c
drivers/gpu/drm/msm/msm_gem.c
drivers/mmc/host/sdhci.c
drivers/net/wireless/ath/ath10k/core.c
kernel/trace/blktrace.c
net/socket.c
sound/core/rawmidi.c
sound/usb/mixer.c
Change-Id: Ic8599e865656da72a9405c45f27091ec1ddc168c
Diffstat (limited to 'block')
| -rw-r--r-- | block/blk-core.c | 3 | ||||
| -rw-r--r-- | block/blk-mq-tag.c | 7 | ||||
| -rw-r--r-- | block/blk-mq.c | 19 | ||||
| -rw-r--r-- | block/blk-timeout.c | 3 |
4 files changed, 30 insertions, 2 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index ea1f8715c8f7..96433980aee4 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -728,6 +728,9 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) kobject_init(&q->kobj, &blk_queue_ktype); +#ifdef CONFIG_BLK_DEV_IO_TRACE + mutex_init(&q->blk_trace_mutex); +#endif mutex_init(&q->sysfs_lock); spin_lock_init(&q->__queue_lock); diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index a07ca3488d96..c1c654319287 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c @@ -481,6 +481,11 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn, struct blk_mq_hw_ctx *hctx; int i; + /* + * Avoid potential races with things like queue removal. + */ + if (!percpu_ref_tryget(&q->q_usage_counter)) + return; queue_for_each_hw_ctx(q, hctx, i) { struct blk_mq_tags *tags = hctx->tags; @@ -497,7 +502,7 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn, bt_for_each(hctx, &tags->bitmap_tags, tags->nr_reserved_tags, fn, priv, false); } - + blk_queue_exit(q); } static unsigned int bt_unused_tags(struct blk_mq_bitmap_tags *bt) diff --git a/block/blk-mq.c b/block/blk-mq.c index d65ddc18d7e4..18d0a0270470 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -628,6 +628,22 @@ static void blk_mq_rq_timer(unsigned long priv) }; int i; + /* A deadlock might occur if a request is stuck requiring a + * timeout at the same time a queue freeze is waiting + * completion, since the timeout code would not be able to + * acquire the queue reference here. + * + * That's why we don't use blk_queue_enter here; instead, we use + * percpu_ref_tryget directly, because we need to be able to + * obtain a reference even in the short window between the queue + * starting to freeze, by dropping the first reference in + * blk_mq_freeze_queue_start, and the moment the last request is + * consumed, marked by the instant q_usage_counter reaches + * zero. + */ + if (!percpu_ref_tryget(&q->q_usage_counter)) + return; + blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &data); if (data.next_set) { @@ -642,6 +658,7 @@ static void blk_mq_rq_timer(unsigned long priv) blk_mq_tag_idle(hctx); } } + blk_queue_exit(q); } /* @@ -1491,7 +1508,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, int to_do; void *p; - while (left < order_to_size(this_order - 1) && this_order) + while (this_order && left < order_to_size(this_order - 1)) this_order--; do { diff --git a/block/blk-timeout.c b/block/blk-timeout.c index aa40aa93381b..2bc03df554a6 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c @@ -134,6 +134,8 @@ void blk_rq_timed_out_timer(unsigned long data) struct request *rq, *tmp; int next_set = 0; + if (blk_queue_enter(q, GFP_NOWAIT)) + return; spin_lock_irqsave(q->queue_lock, flags); list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list) @@ -143,6 +145,7 @@ void blk_rq_timed_out_timer(unsigned long data) mod_timer(&q->timeout, round_jiffies_up(next)); spin_unlock_irqrestore(q->queue_lock, flags); + blk_queue_exit(q); } /** |
