Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753274AbbGNIhj (ORCPT ); Tue, 14 Jul 2015 04:37:39 -0400 Received: from p3plsmtps2ded03.prod.phx3.secureserver.net ([208.109.80.60]:48429 "EHLO p3plsmtps2ded03.prod.phx3.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751994AbbGNIhe (ORCPT ); Tue, 14 Jul 2015 04:37:34 -0400 x-originating-ip: 72.167.245.219 From: Dexuan Cui To: gregkh@linuxfoundation.org, davem@davemloft.net, stephen@networkplumber.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, driverdev-devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com, jasowang@redhat.com, kys@microsoft.com Subject: [V2 7/7] Drivers: hv: vmbus: disable local interrupt when hvsock's callback is running Date: Tue, 14 Jul 2015 03:01:28 -0700 Message-Id: <1436868088-17917-1-git-send-email-decui@microsoft.com> X-Mailer: git-send-email 1.7.4.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1897 Lines: 64 In the SMP guest case, when the per-channel callback hvsock_events() is running on virtual CPU A, if the guest tries to close the connection on virtual CPU B: we invoke vmbus_close() -> vmbus_close_internal(), then we can have trouble: on B, vmbus_close_internal() will send IPI reset_channel_cb() to A, trying to set channel->onchannel_callbackto NULL; on A, if the IPI handler happens between "if (channel->onchannel_callback != NULL)" and invoking channel->onchannel_callback, we'll invoke a function pointer of NULL. This is why the patch is necessary. Signed-off-by: Dexuan Cui --- drivers/hv/connection.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 4fc2e88..4766fd8 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -319,6 +319,9 @@ static void process_chn_event(u32 relid) void *arg; bool read_state; u32 bytes_to_read; + bool is_hvsock = false; + + local_irq_disable(); /* * Find the channel based on this relid and invokes the @@ -327,7 +330,11 @@ static void process_chn_event(u32 relid) channel = pcpu_relid2channel(relid); if (!channel) - return; + goto out; + + is_hvsock = is_hvsock_channel(channel); + if (!is_hvsock) + local_irq_enable(); /* * A channel once created is persistent even when there @@ -363,6 +370,12 @@ static void process_chn_event(u32 relid) bytes_to_read = 0; } while (read_state && (bytes_to_read != 0)); } + + /* local_irq_enable() is alredy invoked above */ + if (!is_hvsock) + return; +out: + local_irq_enable(); } /* -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/