From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755978AbbLLCtj (ORCPT ); Fri, 11 Dec 2015 21:49:39 -0500 Received: from p3plsmtps2ded02.prod.phx3.secureserver.net ([208.109.80.59]:44796 "EHLO p3plsmtps2ded02.prod.phx3.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754694AbbLLCsX (ORCPT ); Fri, 11 Dec 2015 21:48:23 -0500 x-originating-ip: 72.167.245.219 From: "K. Y. Srinivasan" To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com, vkuznets@redhat.com, jasowang@redhat.com Cc: Dexuan Cui , "K. Y. Srinivasan" Subject: [PATCH RESEND 16/27] Drivers: hv: vmbus: serialize process_chn_event() and vmbus_close_internal() Date: Fri, 11 Dec 2015 20:21:36 -0800 Message-Id: <1449894107-3389-16-git-send-email-kys@microsoft.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1449894107-3389-1-git-send-email-kys@microsoft.com> References: <1449894084-3348-1-git-send-email-kys@microsoft.com> <1449894107-3389-1-git-send-email-kys@microsoft.com> X-CMAE-Envelope: MS4wfIFj3KsvCJgTRR29sk0ZAvV4NlIgzGjle9nD0FHC0+MP0FEHElEzhHO81T5GQ038YSa9DHeZb855xwdHbNkUl8Z30McMmMyWBotRJK3CzjrdQK8FOSun aty0/CKjhe523j/fX2v5yXLONyAdlIy8KvsAdsgwS+eMnDxmloAtMvdsNZhBhssnpI7P0O1ANTiYy3tzOzC1Lw1kCG2E3v0g2pywmjyLZ2h9eAW9VJM+V0Pm 26hKm+yjwqosfveCaKkBWeu8oyhoN0ONa++IguRwW9b38XPrn+ynEyWfNzrntiiizYFmW5O1IDPcZ5SzGPSBPUwKAW6IIavEUoiG3Q/F4WCL8OHxWC/uyk2b W2wYC2prBFFAnzNbhYzvpQ3AJkAmQ5DK4m5/k4YioVDM2JX678cGu0Ap+2zDj4UAg3F7sel9CseG7tmegEfOvMgPRHIrlQ== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dexuan Cui process_chn_event(), running in the tasklet, can race with vmbus_close_internal() in the case of SMP guest, e.g., when the former is accessing channel->inbound.ring_buffer, the latter could be freeing the ring_buffer pages. To resolve the race, we can serialize them by disabling the tasklet when the latter is running here. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel.c | 21 +++++++++++++++++++-- 1 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index c4dcab0..f7f3d5c 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "hyperv_vmbus.h" @@ -496,8 +497,21 @@ static void reset_channel_cb(void *arg) static int vmbus_close_internal(struct vmbus_channel *channel) { struct vmbus_channel_close_channel *msg; + struct tasklet_struct *tasklet; int ret; + /* + * process_chn_event(), running in the tasklet, can race + * with vmbus_close_internal() in the case of SMP guest, e.g., when + * the former is accessing channel->inbound.ring_buffer, the latter + * could be freeing the ring_buffer pages. + * + * To resolve the race, we can serialize them by disabling the + * tasklet when the latter is running here. + */ + tasklet = hv_context.event_dpc[channel->target_cpu]; + tasklet_disable(tasklet); + channel->state = CHANNEL_OPEN_STATE; channel->sc_creation_callback = NULL; /* Stop callback and cancel the timer asap */ @@ -525,7 +539,7 @@ static int vmbus_close_internal(struct vmbus_channel *channel) * If we failed to post the close msg, * it is perhaps better to leak memory. */ - return ret; + goto out; } /* Tear down the gpadl for the channel's ring buffer */ @@ -538,7 +552,7 @@ static int vmbus_close_internal(struct vmbus_channel *channel) * If we failed to teardown gpadl, * it is perhaps better to leak memory. */ - return ret; + goto out; } } @@ -555,6 +569,9 @@ static int vmbus_close_internal(struct vmbus_channel *channel) if (channel->rescind) hv_process_channel_removal(channel, channel->offermsg.child_relid); +out: + tasklet_enable(tasklet); + return ret; } -- 1.7.4.1