Merge tag 'module-builtin_driver-v4.1-rc8' of git://git.kernel.org/pub/scm/linux...
[firefly-linux-kernel-4.4.55.git] / drivers / block / null_blk.c
index 65cd61a4145ed2049944621c50b374cf742041ca..69de41a87b74311b2b7478fb0226b8bc253c6ebc 100644 (file)
@@ -99,7 +99,7 @@ static int null_set_queue_mode(const char *str, const struct kernel_param *kp)
        return null_param_store_val(str, &queue_mode, NULL_Q_BIO, NULL_Q_MQ);
 }
 
-static struct kernel_param_ops null_queue_mode_param_ops = {
+static const struct kernel_param_ops null_queue_mode_param_ops = {
        .set    = null_set_queue_mode,
        .get    = param_get_int,
 };
@@ -127,7 +127,7 @@ static int null_set_irqmode(const char *str, const struct kernel_param *kp)
                                        NULL_IRQ_TIMER);
 }
 
-static struct kernel_param_ops null_irqmode_param_ops = {
+static const struct kernel_param_ops null_irqmode_param_ops = {
        .set    = null_set_irqmode,
        .get    = param_get_int,
 };
@@ -243,6 +243,17 @@ static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer)
                        cmd = container_of(entry, struct nullb_cmd, ll_list);
                        entry = entry->next;
                        end_cmd(cmd);
+
+                       if (cmd->rq) {
+                               struct request_queue *q = cmd->rq->q;
+
+                               if (!q->mq_ops && blk_queue_stopped(q)) {
+                                       spin_lock(q->queue_lock);
+                                       if (blk_queue_stopped(q))
+                                               blk_start_queue(q);
+                                       spin_unlock(q->queue_lock);
+                               }
+                       }
                } while (entry);
        }
 
@@ -257,7 +268,7 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd)
        if (llist_add(&cmd->ll_list, &cq->list)) {
                ktime_t kt = ktime_set(0, completion_nsec);
 
-               hrtimer_start(&cq->timer, kt, HRTIMER_MODE_REL);
+               hrtimer_start(&cq->timer, kt, HRTIMER_MODE_REL_PINNED);
        }
 
        put_cpu();
@@ -334,6 +345,7 @@ static int null_rq_prep_fn(struct request_queue *q, struct request *req)
                req->special = cmd;
                return BLKPREP_OK;
        }
+       blk_stop_queue(q);
 
        return BLKPREP_DEFER;
 }