mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
block: don't assume last put of shared tags is for the host
commit d45b3279a5
upstream.
There is no inherent reason why the last put of a tag structure must be
the one for the Scsi_Host, as device model objects can be held for
arbitrary periods. Merge blk_free_tags and __blk_free_tags into a single
funtion that just release a references and get rid of the BUG() when the
host reference wasn't the last.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
82f9c4a309
commit
696acd9dc0
1 changed files with 7 additions and 26 deletions
|
@ -27,18 +27,15 @@ struct request *blk_queue_find_tag(struct request_queue *q, int tag)
|
||||||
EXPORT_SYMBOL(blk_queue_find_tag);
|
EXPORT_SYMBOL(blk_queue_find_tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __blk_free_tags - release a given set of tag maintenance info
|
* blk_free_tags - release a given set of tag maintenance info
|
||||||
* @bqt: the tag map to free
|
* @bqt: the tag map to free
|
||||||
*
|
*
|
||||||
* Tries to free the specified @bqt. Returns true if it was
|
* Drop the reference count on @bqt and frees it when the last reference
|
||||||
* actually freed and false if there are still references using it
|
* is dropped.
|
||||||
*/
|
*/
|
||||||
static int __blk_free_tags(struct blk_queue_tag *bqt)
|
void blk_free_tags(struct blk_queue_tag *bqt)
|
||||||
{
|
{
|
||||||
int retval;
|
if (atomic_dec_and_test(&bqt->refcnt)) {
|
||||||
|
|
||||||
retval = atomic_dec_and_test(&bqt->refcnt);
|
|
||||||
if (retval) {
|
|
||||||
BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
|
BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
|
||||||
bqt->max_depth);
|
bqt->max_depth);
|
||||||
|
|
||||||
|
@ -50,9 +47,8 @@ static int __blk_free_tags(struct blk_queue_tag *bqt)
|
||||||
|
|
||||||
kfree(bqt);
|
kfree(bqt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(blk_free_tags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __blk_queue_free_tags - release tag maintenance info
|
* __blk_queue_free_tags - release tag maintenance info
|
||||||
|
@ -69,27 +65,12 @@ void __blk_queue_free_tags(struct request_queue *q)
|
||||||
if (!bqt)
|
if (!bqt)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
__blk_free_tags(bqt);
|
blk_free_tags(bqt);
|
||||||
|
|
||||||
q->queue_tags = NULL;
|
q->queue_tags = NULL;
|
||||||
queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
|
queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* blk_free_tags - release a given set of tag maintenance info
|
|
||||||
* @bqt: the tag map to free
|
|
||||||
*
|
|
||||||
* For externally managed @bqt frees the map. Callers of this
|
|
||||||
* function must guarantee to have released all the queues that
|
|
||||||
* might have been using this tag map.
|
|
||||||
*/
|
|
||||||
void blk_free_tags(struct blk_queue_tag *bqt)
|
|
||||||
{
|
|
||||||
if (unlikely(!__blk_free_tags(bqt)))
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(blk_free_tags);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* blk_queue_free_tags - release tag maintenance info
|
* blk_queue_free_tags - release tag maintenance info
|
||||||
* @q: the request queue for the device
|
* @q: the request queue for the device
|
||||||
|
|
Loading…
Reference in a new issue