aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/badblocks.c23
-rw-r--r--block/blk-flush.c28
-rw-r--r--block/blk-mq.c6
-rw-r--r--drivers/block/nbd.c2
-rw-r--r--kernel/softirq.c2
5 files changed, 56 insertions, 5 deletions
diff --git a/block/badblocks.c b/block/badblocks.c
index 6610e282a03e..6ebcef282314 100644
--- a/block/badblocks.c
+++ b/block/badblocks.c
@@ -133,6 +133,26 @@ retry:
133} 133}
134EXPORT_SYMBOL_GPL(badblocks_check); 134EXPORT_SYMBOL_GPL(badblocks_check);
135 135
136static void badblocks_update_acked(struct badblocks *bb)
137{
138 u64 *p = bb->page;
139 int i;
140 bool unacked = false;
141
142 if (!bb->unacked_exist)
143 return;
144
145 for (i = 0; i < bb->count ; i++) {
146 if (!BB_ACK(p[i])) {
147 unacked = true;
148 break;
149 }
150 }
151
152 if (!unacked)
153 bb->unacked_exist = 0;
154}
155
136/** 156/**
137 * badblocks_set() - Add a range of bad blocks to the table. 157 * badblocks_set() - Add a range of bad blocks to the table.
138 * @bb: the badblocks structure that holds all badblock information 158 * @bb: the badblocks structure that holds all badblock information
@@ -294,6 +314,8 @@ int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
294 bb->changed = 1; 314 bb->changed = 1;
295 if (!acknowledged) 315 if (!acknowledged)
296 bb->unacked_exist = 1; 316 bb->unacked_exist = 1;
317 else
318 badblocks_update_acked(bb);
297 write_sequnlock_irqrestore(&bb->lock, flags); 319 write_sequnlock_irqrestore(&bb->lock, flags);
298 320
299 return rv; 321 return rv;
@@ -401,6 +423,7 @@ int badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
401 } 423 }
402 } 424 }
403 425
426 badblocks_update_acked(bb);
404 bb->changed = 1; 427 bb->changed = 1;
405out: 428out:
406 write_sequnlock_irq(&bb->lock); 429 write_sequnlock_irq(&bb->lock);
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 6a14b68b9135..3c882cbc7541 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -343,6 +343,34 @@ static void flush_data_end_io(struct request *rq, int error)
343 struct blk_flush_queue *fq = blk_get_flush_queue(q, NULL); 343 struct blk_flush_queue *fq = blk_get_flush_queue(q, NULL);
344 344
345 /* 345 /*
346 * Updating q->in_flight[] here for making this tag usable
347 * early. Because in blk_queue_start_tag(),
348 * q->in_flight[BLK_RW_ASYNC] is used to limit async I/O and
349 * reserve tags for sync I/O.
350 *
351 * More importantly this way can avoid the following I/O
352 * deadlock:
353 *
354 * - suppose there are 40 fua requests comming to flush queue
355 * and queue depth is 31
356 * - 30 rqs are scheduled then blk_queue_start_tag() can't alloc
357 * tag for async I/O any more
358 * - all the 30 rqs are completed before FLUSH_PENDING_TIMEOUT
359 * and flush_data_end_io() is called
360 * - the other rqs still can't go ahead if not updating
361 * q->in_flight[BLK_RW_ASYNC] here, meantime these rqs
362 * are held in flush data queue and make no progress of
363 * handling post flush rq
364 * - only after the post flush rq is handled, all these rqs
365 * can be completed
366 */
367
368 elv_completed_request(q, rq);
369
370 /* for avoiding double accounting */
371 rq->cmd_flags &= ~REQ_STARTED;
372
373 /*
346 * After populating an empty queue, kick it to avoid stall. Read 374 * After populating an empty queue, kick it to avoid stall. Read
347 * the comment in flush_end_io(). 375 * the comment in flush_end_io().
348 */ 376 */
diff --git a/block/blk-mq.c b/block/blk-mq.c
index ddc2eed64771..f3d27a6dee09 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1217,9 +1217,9 @@ static struct request *blk_mq_map_request(struct request_queue *q,
1217 blk_mq_set_alloc_data(&alloc_data, q, 0, ctx, hctx); 1217 blk_mq_set_alloc_data(&alloc_data, q, 0, ctx, hctx);
1218 rq = __blk_mq_alloc_request(&alloc_data, op, op_flags); 1218 rq = __blk_mq_alloc_request(&alloc_data, op, op_flags);
1219 1219
1220 hctx->queued++; 1220 data->hctx = alloc_data.hctx;
1221 data->hctx = hctx; 1221 data->ctx = alloc_data.ctx;
1222 data->ctx = ctx; 1222 data->hctx->queued++;
1223 return rq; 1223 return rq;
1224} 1224}
1225 1225
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index ba405b55329f..19a16b2dbb91 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -164,7 +164,7 @@ static void sock_shutdown(struct nbd_device *nbd)
164 spin_lock(&nbd->sock_lock); 164 spin_lock(&nbd->sock_lock);
165 165
166 if (!nbd->sock) { 166 if (!nbd->sock) {
167 spin_unlock_irq(&nbd->sock_lock); 167 spin_unlock(&nbd->sock_lock);
168 return; 168 return;
169 } 169 }
170 170
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 1bf81ef91375..744fa611cae0 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -58,7 +58,7 @@ static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp
58DEFINE_PER_CPU(struct task_struct *, ksoftirqd); 58DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
59 59
60const char * const softirq_to_name[NR_SOFTIRQS] = { 60const char * const softirq_to_name[NR_SOFTIRQS] = {
61 "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL", 61 "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "IRQ_POLL",
62 "TASKLET", "SCHED", "HRTIMER", "RCU" 62 "TASKLET", "SCHED", "HRTIMER", "RCU"
63}; 63};
64 64