struct request_list *rl = blk_rq_rl(req);
 
                BUG_ON(!list_empty(&req->queuelist));
-               BUG_ON(!hlist_unhashed(&req->hash));
+               BUG_ON(ELV_ON_HASH(req));
 
                blk_free_request(rl, req);
                freed_request(rl, flags);
 
        while (!list_empty(&local_list)) {
                struct request *rq;
 
-               rq = list_entry(local_list.next, struct request, queuelist);
-               list_del_init(&rq->queuelist);
+               rq = list_entry(local_list.next, struct request, ipi_list);
+               list_del_init(&rq->ipi_list);
                rq->q->softirq_done_fn(rq);
        }
 }
 
        local_irq_save(flags);
        list = this_cpu_ptr(&blk_cpu_done);
-       /*
-        * We reuse queuelist for a list of requests to process. Since the
-        * queuelist is used by the block layer only for requests waiting to be
-        * submitted to the device it is unused now.
-        */
-       list_add_tail(&rq->queuelist, list);
+       list_add_tail(&rq->ipi_list, list);
 
-       if (list->next == &rq->queuelist)
+       if (list->next == &rq->ipi_list)
                raise_softirq_irqoff(BLOCK_SOFTIRQ);
 
        local_irq_restore(flags);
                struct list_head *list;
 do_local:
                list = this_cpu_ptr(&blk_cpu_done);
-               list_add_tail(&req->queuelist, list);
+               list_add_tail(&req->ipi_list, list);
 
                /*
                 * if the list only contains our just added request,
                 * entries there, someone already raised the irq but it
                 * hasn't run yet.
                 */
-               if (list->next == &req->queuelist)
+               if (list->next == &req->ipi_list)
                        raise_softirq_irqoff(BLOCK_SOFTIRQ);
        } else if (raise_blk_irq(ccpu, req))
                goto do_local;
 
 /*
  * Internal elevator interface
  */
-#define ELV_ON_HASH(rq) hash_hashed(&(rq)->hash)
+#define ELV_ON_HASH(rq) ((rq)->cmd_flags & REQ_HASHED)
 
 void blk_insert_flush(struct request *rq);
 void blk_abort_flushes(struct request_queue *q);
 
 static inline void __elv_rqhash_del(struct request *rq)
 {
        hash_del(&rq->hash);
+       rq->cmd_flags &= ~REQ_HASHED;
 }
 
 static void elv_rqhash_del(struct request_queue *q, struct request *rq)
 
        BUG_ON(ELV_ON_HASH(rq));
        hash_add(e->hash, &rq->hash, rq_hash_key(rq));
+       rq->cmd_flags |= REQ_HASHED;
 }
 
 static void elv_rqhash_reposition(struct request_queue *q, struct request *rq)
 
        __REQ_KERNEL,           /* direct IO to kernel pages */
        __REQ_PM,               /* runtime pm request */
        __REQ_END,              /* last of chain of requests */
+       __REQ_HASHED,           /* on IO scheduler merge hash */
        __REQ_NR_BITS,          /* stops here */
 };
 
 #define REQ_KERNEL             (1ULL << __REQ_KERNEL)
 #define REQ_PM                 (1ULL << __REQ_PM)
 #define REQ_END                        (1ULL << __REQ_END)
+#define REQ_HASHED             (1ULL << __REQ_HASHED)
 
 #endif /* __LINUX_BLK_TYPES_H */
 
        struct bio *bio;
        struct bio *biotail;
 
-       struct hlist_node hash; /* merge hash */
+       /*
+        * The hash is used inside the scheduler, and killed once the
+        * request reaches the dispatch list. The ipi_list is only used
+        * to queue the request for softirq completion, which is long
+        * after the request has been unhashed (and even removed from
+        * the dispatch list).
+        */
+       union {
+               struct hlist_node hash; /* merge hash */
+               struct list_head ipi_list;
+       };
+
        /*
         * The rb_node is only used inside the io scheduler, requests
         * are pruned when moved to the dispatch queue. So let the