linux/block/blk-mq.c
/*
 * Mark us waiting for a tag. For shared tags, this involves hooking us into
 * the tag wakeups. For non-shared tags, we can simply mark us needing a
 * restart. For both cases, take care to check the condition again after
 * marking us as waiting.
 */
Mark us waiting for a tag. For shared tags, this involves hooking us into
the tag wakeups. For non-shared tags, we can simply mark us needing a
restart. For both cases, take care to check the condition again after
marking us as waiting.
Mark us waiting for a tag . For shared tags this involves hooking us into the tag wakeups . For non - shared tags we can simply mark us needing a restart . For both cases take care to check the condition again after marking us as waiting .
static bool blk_mq_mark_tag_wait(struct blk_mq_hw_ctx *hctx,
				 struct request *rq)
{
	struct wait_queue_head *wq;
	wait_queue_entry_t *wait;
	bool ret;
	if (!(hctx->flags & BLK_MQ_F_TAG_SHARED)) {
		if (!test_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state))
			set_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
		return blk_mq_get_driver_tag(rq);
	}
	wait = &hctx->dispatch_wait;
	if (!list_empty_careful(&wait->entry))
		return false;
	wq = &bt_wait_ptr(&hctx->tags->bitmap_tags, hctx)->wait;
	spin_lock_irq(&wq->lock);
	spin_lock(&hctx->dispatch_wait_lock);
	if (!list_empty(&wait->entry)) {
		spin_unlock(&hctx->dispatch_wait_lock);
		spin_unlock_irq(&wq->lock);
		return false;
	}
	wait->flags &= ~WQ_FLAG_EXCLUSIVE;
	__add_wait_queue(wq, wait);
	ret = blk_mq_get_driver_tag(rq);
	if (!ret) {
		spin_unlock(&hctx->dispatch_wait_lock);
		spin_unlock_irq(&wq->lock);
		return false;
	}
	list_del_init(&wait->entry);
	spin_unlock(&hctx->dispatch_wait_lock);
	spin_unlock_irq(&wq->lock);
	return true;
}
static bool blk_mq_mark_tag_wait ( struct blk_mq_hw_ctx * hctx , struct request * rq ) { struct wait_queue_head * wq ; wait_queue_entry_t * wait ; bool ret ; if ( ! ( hctx -> flags & BLK_MQ_F_TAG_SHARED ) ) { if ( ! test_bit ( BLK_MQ_S_SCHED_RESTART , & hctx -> state ) ) set_bit ( BLK_MQ_S_SCHED_RESTART , & hctx -> state ) ; return blk_mq_get_driver_tag ( rq ) ; } wait = & hctx -> dispatch_wait ; if ( ! list_empty_careful ( & wait -> entry ) ) return false ; wq = & bt_wait_ptr ( & hctx -> tags -> bitmap_tags , hctx ) -> wait ; spin_lock_irq ( & wq -> lock ) ; spin_lock ( & hctx -> dispatch_wait_lock ) ; if ( ! list_empty ( & wait -> entry ) ) { spin_unlock ( & hctx -> dispatch_wait_lock ) ; spin_unlock_irq ( & wq -> lock ) ; return false ; } wait -> flags &= ~ WQ_FLAG_EXCLUSIVE ; __add_wait_queue ( wq , wait ) ; ret = blk_mq_get_driver_tag ( rq ) ; if ( ! ret ) { spin_unlock ( & hctx -> dispatch_wait_lock ) ; spin_unlock_irq ( & wq -> lock ) ; return false ; } list_del_init ( & wait -> entry ) ; spin_unlock ( & hctx -> dispatch_wait_lock ) ; spin_unlock_irq ( & wq -> lock ) ; return true ; }
Mark us waiting for a tag.
Mark us waiting for a tag .
/*
		 * It's possible that a tag was freed in the window between the
		 * allocation failure and adding the hardware queue to the wait
		 * queue.
		 *
		 * Don't clear RESTART here, someone else could have set it.
		 * At most this will cost an extra queue run.
		 */ /*
	 * It's possible that a tag was freed in the window between the
	 * allocation failure and adding the hardware queue to the wait
	 * queue.
	 */ /*
	 * We got a tag, remove ourselves from the wait queue to ensure
	 * someone else gets the wakeup.
	 */