From patchwork Tue Jul 14 10:01:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dexuan Cui X-Patchwork-Id: 494942 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id D44151402D9 for ; Tue, 14 Jul 2015 18:38:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753075AbbGNIhj (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 Received: from linuxonhyperv.com ([72.167.245.219]) by p3plsmtps2ded03.prod.phx3.secureserver.net with : DED : id s8dZ1q00T4kklxU018dZ6l; Tue, 14 Jul 2015 01:37:33 -0700 x-originating-ip: 72.167.245.219 Received: by linuxonhyperv.com (Postfix, from userid 518) id 6FD461901E2; Tue, 14 Jul 2015 03:01:28 -0700 (PDT) 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: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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(); } /*