Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp2003620imm; Thu, 24 May 2018 04:21:15 -0700 (PDT) X-Google-Smtp-Source: AB8JxZr6/gkaAi7aKgieV5g9p6kzd/aojCJMubL58PrVNWCm7cEckF05qkeFpHgk9/oNcaZnc2/H X-Received: by 2002:a17:902:9a8a:: with SMTP id w10-v6mr6992399plp.333.1527160874999; Thu, 24 May 2018 04:21:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527160874; cv=none; d=google.com; s=arc-20160816; b=go5QDPYPhUSQZmmT2SNX6nGoxmIH3VSHIuu+wWRuNKLQqqNySUSheFMhVlg9ZuGGn4 Z5ISGZ5h9EXuY8CURcAjpQ8aKnpeVEywcmOF67GY4J1aCzHF3VWECef2G5F/v2HepUlb PbASyI9Uz2G6gmUTFWE2CcJe7Ekk9F80xkZFzaqYNLzMvmJGXnzCzd1fx07JYem+H21j BgCBIK1fVOdLHCjsy+2WAtcE9lluFKOz7gQpfyt8R8FARqk5tWImtth80Ruga61LW724 QR54Efj81Q1lpLqsb+XZgUtNWTbRG7bDQGt2uU2VzFjAwiBm3zqUftJquYrbnBlgFB8J pquQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=y9D/yla6vsH0LMnFyUIYOMrA+2N2gnGqRNaPk5IVDiM=; b=Avt2D5ScDegMwsYduKOZtgQ0sjhh5Df1zQhNGwqL3iQHCU4tHzZRfb3KT/Xyw9uRhI 818BRc7oB5NOfwB5eLIR8JDgpGzP3YSJwchSc4GI382QULX2+Lz+yrmhJNmGwqrXghTo XD7zf+6miJ8JezKmCLHG2zamk9T9sXt0zwmBFiEigQw2ja+o0te24vuVydFcJTzg/Dga 1cKN1j3+5h6FLPYWbtVfxczC4IKcxHKv7ZdLeAwuBc/3kALKUiFcj8TPw4tzcBnIGl3I 5B/2xc3d6C7pLN4gtSC97Z46zNzJ3QtQi7qYoJtDs4MludwuS9xusYRuZNHYtp3mpumE z9Dw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=A5eb7z6f; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v9-v6si21623447plg.124.2018.05.24.04.21.00; Thu, 24 May 2018 04:21:14 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=A5eb7z6f; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S967902AbeEXJwh (ORCPT + 99 others); Thu, 24 May 2018 05:52:37 -0400 Received: from mail.kernel.org ([198.145.29.99]:52022 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S967868AbeEXJw1 (ORCPT ); Thu, 24 May 2018 05:52:27 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6A10E20847; Thu, 24 May 2018 09:52:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1527155546; bh=tTadi+Hz0s0dx+F0aPKGjPAqcoKVCk14sn63bJNQRAE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A5eb7z6fHT/ArcHKpVl7YoHSx8vSnJUBC79OZSza2McelxOa/+LUpKIqthTitrXVN +ahigf6ZJ9cGkyoG2wc9s5WTUMiOx6X9Yt995NYnWF4Ia5j2LTTZ82+DWcjrbtNpLq 2m6etXvOuJggczOH2HQPGN/px2/r5dZov+LsYGdY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Stephen Hemminger , "David S. Miller" Subject: [PATCH 4.14 028/165] hv_netvsc: use RCU to fix concurrent rx and queue changes Date: Thu, 24 May 2018 11:37:14 +0200 Message-Id: <20180524093623.116952569@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180524093621.979359379@linuxfoundation.org> References: <20180524093621.979359379@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Stephen Hemminger [ Commit 02400fcee2542ee334a2394e0d9f6efd969fe782 upstream. ] The receive processing may continue to happen while the internal network device state is in RCU grace period. The internal RNDIS structure is associated with the internal netvsc_device structure; both have the same RCU lifetime. Defer freeing all associated parts until after grace period. Fixes: 0cf737808ae7 ("hv_netvsc: netvsc_teardown_gpadl() split") Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/hyperv/netvsc.c | 17 ++++------------ drivers/net/hyperv/rndis_filter.c | 39 ++++++++++++++++---------------------- 2 files changed, 22 insertions(+), 34 deletions(-) --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -89,6 +89,11 @@ static void free_netvsc_device(struct rc = container_of(head, struct netvsc_device, rcu); int i; + kfree(nvdev->extension); + vfree(nvdev->recv_buf); + vfree(nvdev->send_buf); + kfree(nvdev->send_section_map); + for (i = 0; i < VRSS_CHANNEL_MAX; i++) vfree(nvdev->chan_table[i].mrc.slots); @@ -210,12 +215,6 @@ static void netvsc_teardown_gpadl(struct net_device->recv_buf_gpadl_handle = 0; } - if (net_device->recv_buf) { - /* Free up the receive buffer */ - vfree(net_device->recv_buf); - net_device->recv_buf = NULL; - } - if (net_device->send_buf_gpadl_handle) { ret = vmbus_teardown_gpadl(device->channel, net_device->send_buf_gpadl_handle); @@ -230,12 +229,6 @@ static void netvsc_teardown_gpadl(struct } net_device->send_buf_gpadl_handle = 0; } - if (net_device->send_buf) { - /* Free up the send buffer */ - vfree(net_device->send_buf); - net_device->send_buf = NULL; - } - kfree(net_device->send_section_map); } int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx) --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -266,13 +266,23 @@ static void rndis_set_link_state(struct } } -static void rndis_filter_receive_response(struct rndis_device *dev, - struct rndis_message *resp) +static void rndis_filter_receive_response(struct net_device *ndev, + struct netvsc_device *nvdev, + const struct rndis_message *resp) { + struct rndis_device *dev = nvdev->extension; struct rndis_request *request = NULL; bool found = false; unsigned long flags; - struct net_device *ndev = dev->ndev; + + /* This should never happen, it means control message + * response received after device removed. + */ + if (dev->state == RNDIS_DEV_UNINITIALIZED) { + netdev_err(ndev, + "got rndis message uninitialized\n"); + return; + } spin_lock_irqsave(&dev->request_lock, flags); list_for_each_entry(request, &dev->req_list, list_ent) { @@ -353,7 +363,7 @@ static inline void *rndis_get_ppi(struct } static int rndis_filter_receive_data(struct net_device *ndev, - struct rndis_device *dev, + struct netvsc_device *nvdev, struct rndis_message *msg, struct vmbus_channel *channel, void *data, u32 data_buflen) @@ -373,7 +383,7 @@ static int rndis_filter_receive_data(str * should be the data packet size plus the trailer padding size */ if (unlikely(data_buflen < rndis_pkt->data_len)) { - netdev_err(dev->ndev, "rndis message buffer " + netdev_err(ndev, "rndis message buffer " "overflow detected (got %u, min %u)" "...dropping this message!\n", data_buflen, rndis_pkt->data_len); @@ -401,34 +411,20 @@ int rndis_filter_receive(struct net_devi void *data, u32 buflen) { struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct rndis_device *rndis_dev = net_dev->extension; struct rndis_message *rndis_msg = data; - /* Make sure the rndis device state is initialized */ - if (unlikely(!rndis_dev)) { - netif_err(net_device_ctx, rx_err, ndev, - "got rndis message but no rndis device!\n"); - return NVSP_STAT_FAIL; - } - - if (unlikely(rndis_dev->state == RNDIS_DEV_UNINITIALIZED)) { - netif_err(net_device_ctx, rx_err, ndev, - "got rndis message uninitialized\n"); - return NVSP_STAT_FAIL; - } - if (netif_msg_rx_status(net_device_ctx)) dump_rndis_message(dev, rndis_msg); switch (rndis_msg->ndis_msg_type) { case RNDIS_MSG_PACKET: - return rndis_filter_receive_data(ndev, rndis_dev, rndis_msg, + return rndis_filter_receive_data(ndev, net_dev, rndis_msg, channel, data, buflen); case RNDIS_MSG_INIT_C: case RNDIS_MSG_QUERY_C: case RNDIS_MSG_SET_C: /* completion msgs */ - rndis_filter_receive_response(rndis_dev, rndis_msg); + rndis_filter_receive_response(ndev, net_dev, rndis_msg); break; case RNDIS_MSG_INDICATE: @@ -1349,7 +1345,6 @@ void rndis_filter_device_remove(struct h net_dev->extension = NULL; netvsc_device_remove(dev); - kfree(rndis_dev); } int rndis_filter_open(struct netvsc_device *nvdev)