Staging: hv: vmbus: Properly deal with de-registering channel callback
Ensure that we correctly handle racing invocations of the channel callback
when the channel is being closed. We do this using the channel's inbound_lock.
A side-effect of this strategy is that we avoid repeatedly picking up this lock
as we drain the inbound ring-buffer.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
index 7a3ec75..6aab802 100644
--- a/drivers/staging/hv/connection.c
+++ b/drivers/staging/hv/connection.c
@@ -215,6 +215,7 @@
static void process_chn_event(u32 relid)
{
struct vmbus_channel *channel;
+ unsigned long flags;
/*
* Find the channel based on this relid and invokes the
@@ -222,11 +223,13 @@
*/
channel = relid2channel(relid);
+ spin_lock_irqsave(&channel->inbound_lock, flags);
if (channel && (channel->onchannel_callback != NULL)) {
channel->onchannel_callback(channel->channel_callback_context);
} else {
pr_err("channel not found for relid - %u\n", relid);
}
+ spin_unlock_irqrestore(&channel->inbound_lock, flags);
}
/*