Skip to content

Commit

Permalink
block: don't assume last put of shared tags is for the host
Browse files Browse the repository at this point in the history
commit d45b327 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 <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
  • Loading branch information
Christoph Hellwig authored and Jiri Slaby committed Jul 30, 2014
1 parent be8e936 commit b786221
Showing 1 changed file with 7 additions and 26 deletions.
33 changes: 7 additions & 26 deletions block/blk-tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,15 @@ struct request *blk_queue_find_tag(struct request_queue *q, int 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
*
* Tries to free the specified @bqt. Returns true if it was
* actually freed and false if there are still references using it
* Drop the reference count on @bqt and frees it when the last reference
* is dropped.
*/
static int __blk_free_tags(struct blk_queue_tag *bqt)
void blk_free_tags(struct blk_queue_tag *bqt)
{
int retval;

retval = atomic_dec_and_test(&bqt->refcnt);
if (retval) {
if (atomic_dec_and_test(&bqt->refcnt)) {
BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
bqt->max_depth);

Expand All @@ -50,9 +47,8 @@ static int __blk_free_tags(struct blk_queue_tag *bqt)

kfree(bqt);
}

return retval;
}
EXPORT_SYMBOL(blk_free_tags);

/**
* __blk_queue_free_tags - release tag maintenance info
Expand All @@ -69,27 +65,12 @@ void __blk_queue_free_tags(struct request_queue *q)
if (!bqt)
return;

__blk_free_tags(bqt);
blk_free_tags(bqt);

q->queue_tags = NULL;
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
* @q: the request queue for the device
Expand Down

0 comments on commit b786221

Please sign in to comment.