summaryrefslogtreecommitdiff
path: root/drivers/soc/qcom/hab
diff options
context:
space:
mode:
authorYao Jiang <yaojia@codeaurora.org>2018-09-27 11:53:55 +0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-10-07 18:33:31 -0700
commit3acc958e8df36b84ee25c950b1f7e39931a6e0bc (patch)
tree5c8cc37b1fcc315d4f1b48308ebb39c1229ec0f4 /drivers/soc/qcom/hab
parent3b8fc0b7a3fcc809378d82dbf66b417e186af205 (diff)
soc: qcom: hab: replace kref_get with kref_get_unless_zero
If refcount was 0 before increment, it maybe has a race condition that this kref is freeing by some other thread right now. In this case we should not increments refcount, so replace with kref_get_unless_zero. Change-Id: Ic15eaefc111770a966094d05b19eca2a04d52fc2 Signed-off-by: Yao Jiang <yaojia@codeaurora.org>
Diffstat (limited to 'drivers/soc/qcom/hab')
-rw-r--r--drivers/soc/qcom/hab/hab.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/soc/qcom/hab/hab.c b/drivers/soc/qcom/hab/hab.c
index db4961f5f15f..5b84a57423b9 100644
--- a/drivers/soc/qcom/hab/hab.c
+++ b/drivers/soc/qcom/hab/hab.c
@@ -218,7 +218,15 @@ struct virtual_channel *hab_get_vchan_fromvcid(int32_t vcid,
read_lock(&ctx->ctx_lock);
list_for_each_entry(vchan, &ctx->vchannels, node) {
if (vcid == vchan->id) {
- kref_get(&vchan->refcount);
+ if (vchan->otherend_closed || vchan->closed ||
+ !kref_get_unless_zero(&vchan->refcount)) {
+ pr_debug("failed to inc vcid %x remote %x session %d refcnt %d close_flg remote %d local %d\n",
+ vchan->id, vchan->otherend_id,
+ vchan->session_id,
+ get_refcnt(vchan->refcount),
+ vchan->otherend_closed, vchan->closed);
+ vchan = NULL;
+ }
read_unlock(&ctx->ctx_lock);
return vchan;
}