Received: by 10.213.65.68 with SMTP id h4csp57675imn; Thu, 15 Mar 2018 09:25:44 -0700 (PDT) X-Google-Smtp-Source: AG47ELvnIw+X0sAh0X+TXXj9JCK8uKwuXUE1DBm7PPWka1ds254RFTJ9EwDoRF4OtIF3hOHndVWx X-Received: by 2002:a17:902:6e8c:: with SMTP id v12-v6mr8667553plk.24.1521131144524; Thu, 15 Mar 2018 09:25:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521131144; cv=none; d=google.com; s=arc-20160816; b=dLlzq9MN0gieoIPwWvTNc/sNdlccoashzamYamePKiB8OuwiRa3EMhsoib4SE72c4H mdD8Nn1TabVJZpKdkL8F+KMpFP6+85UMtPuAM7L8O2535nG/1xuXUChUhnWaWX0CkiVs AkyCDLdOtefcWnDR5pODSTuYeHFP4aAOWi5/r9GOQoX9L6OeiLwcmsZ1+Y0US/yLHjYI NumtHhRLjk8RaD0dXYtpU4HPy+TI3lEEepsFE/i8TltzW1Vr4Wu1Q7cQne/217nih4zo 6au2Ba7hqnhMRZ3srA60r5Wtt/hK0PbgW4suGgZHw6Q8Mgok5gQPp3Ew1R/mqpR0BmQ6 X4FQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :organization:references:in-reply-to:date:cc:to:reply-to:from :subject:message-id:arc-authentication-results; bh=d/Mo5FrZc9Y57TRVVY6ZHUa4N1nlwB2R83mHgBoIx3I=; b=oIU/MNUgwxkIKmWah2qQ6CxHxkwIDm5/nVHO2mn99wNOcNtELqR7tsay36V7tOrlAs 4oojIxDL/GHv3Gm0KpLa0F4pd20xkJX/qXSWKyvaMbYCg/dBebkU0mD+1EHJ+La85+hK /F7e0Fd4NUxIyE3r3x3ifjAqH2HkLazRoVcEx1lI96xLuPh8qcWGvvZG3LieNJ+z2eoc UeYdyynPdN3PRa0hKrOhcap7xuftJRgTSj0LlAciqHBTkGjxv0lOdwkIe90Hj2TKJFar GseKFSBL9XSZZbOo2j6zsUBtHbHnxHuMay6bkMLR+v+CN/KJaBoG9j67AXWmy0w0OozN 4PYQ== ARC-Authentication-Results: i=1; mx.google.com; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z16-v6si2509537pll.36.2018.03.15.09.25.29; Thu, 15 Mar 2018 09:25:44 -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; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751657AbeCOQYV (ORCPT + 99 others); Thu, 15 Mar 2018 12:24:21 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:54056 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750987AbeCOQYT (ORCPT ); Thu, 15 Mar 2018 12:24:19 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1A151406E8D2; Thu, 15 Mar 2018 16:24:19 +0000 (UTC) Received: from ovpn-112-35.ams2.redhat.com (ovpn-112-35.ams2.redhat.com [10.36.112.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7546EC1235; Thu, 15 Mar 2018 16:24:14 +0000 (UTC) Message-ID: <1521131053.30828.1.camel@redhat.com> Subject: Re: [PATCH] hv_netvsc: Make sure out channel is fully opened on send From: Mohammed Gamal Reply-To: mgamal@redhat.com To: Stephen Hemminger Cc: netdev@vger.kernel.org, sthemmin@microsoft.com, otubo@redhat.com, linux-kernel@vger.kernel.org, devel@linuxdriverproject.org, vkuznets@redhat.com, davem@davemloft.net Date: Thu, 15 Mar 2018 17:24:13 +0100 In-Reply-To: <1521019321.8260.1.camel@redhat.com> References: <1520968010-20733-1-git-send-email-mgamal@redhat.com> <20180313123521.5b486da1@xeon-e3> <1521019321.8260.1.camel@redhat.com> Organization: Red Hat Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Thu, 15 Mar 2018 16:24:19 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Thu, 15 Mar 2018 16:24:19 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'mgamal@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 2018-03-14 at 10:22 +0100, Mohammed Gamal wrote: > On Tue, 2018-03-13 at 12:35 -0700, Stephen Hemminger wrote: > > On Tue, 13 Mar 2018 20:06:50 +0100 > > Mohammed Gamal wrote: > > > > > Dring high network traffic changes to network interface > > > parameters > > > such as number of channels or MTU can cause a kernel panic with a > > > NULL > > > pointer dereference. This is due to netvsc_device_remove() being > > > called and deallocating the channel ring buffers, which can then > > > be > > > accessed by netvsc_send_pkt() before they're allocated on calling > > > netvsc_device_add() > > > > > > The patch fixes this problem by checking the channel state and > > > returning > > > ENODEV if not yet opened. We also move the call to > > > hv_ringbuf_avail_percent() > > > which may access the uninitialized ring buffer. > > > > > > Signed-off-by: Mohammed Gamal > > > --- > > >  drivers/net/hyperv/netvsc.c | 5 +++-- > > >  1 file changed, 3 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/net/hyperv/netvsc.c > > > b/drivers/net/hyperv/netvsc.c > > > index 0265d70..44a8358 100644 > > > --- a/drivers/net/hyperv/netvsc.c > > > +++ b/drivers/net/hyperv/netvsc.c > > > @@ -757,7 +757,7 @@ static inline int netvsc_send_pkt( > > >   struct netdev_queue *txq = netdev_get_tx_queue(ndev, > > > packet->q_idx); > > >   u64 req_id; > > >   int ret; > > > - u32 ring_avail = hv_ringbuf_avail_percent(&out_channel- > > > > outbound); > > > > > > + u32 ring_avail; > > >   > > >   nvmsg.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT; > > >   if (skb) > > > @@ -773,7 +773,7 @@ static inline int netvsc_send_pkt( > > >   > > >   req_id = (ulong)skb; > > >   > > > - if (out_channel->rescind) > > > + if (out_channel->rescind || out_channel->state != > > > CHANNEL_OPENED_STATE) > > >   return -ENODEV; > > >   > > >   if (packet->page_buf_cnt) { > > > @@ -791,6 +791,7 @@ static inline int netvsc_send_pkt( > > >          VMBUS_DATA_PACKET_FLAG_CO > > > MP > > > LETION_REQUESTED); > > >   } > > >   > > > + ring_avail = hv_ringbuf_avail_percent(&out_channel- > > > > outbound); > > > > > >   if (ret == 0) { > > >   atomic_inc_return(&nvchan->queue_sends); > > >   > > > > Thanks for your patch. Yes there are races with the current update > > logic. The root cause goes higher up in the flow; the send queues > > should > > be stopped before netvsc_device_remove is called. Solving it where > > you tried > > to is racy and not going to work reliably. > > > > Network patches should go to netdev@vger.kernel.org > > > > You can't move the ring_avail check until after the > > vmbus_sendpacket > > because > > that will break the flow control logic. > > > > Why? I don't see ring_avail being used before that point. Ah, stupid me. vmbus_sendpacket() will write to the ring buffer and that means that ring_avail value will be different than the expected. > > > Instead, you should just move the avail_read check until just after > > the existing rescind > > check. > > > > Also, you shouldn't need to check for OPENED_STATE, just rescind is > > enough. > > That rarely mitigated the race. channel->rescind flag is set on vmbus > exit - called on module unload - and when a rescind offer is received > from the host, which AFAICT doesn't happen on every call to > netvsc_device_remove, so it's quite possible that the ringbuffer is > accessed before it's allocated again on channel open and hence the > check for OPENED_STAT - which is only set after all vmbus data is > initialized. > Perhaps I haven't been clear enough. The NULL pointer dereference happens in the call to hv_ringbuf_avail_percent() which is used to calculate ring_avail.  So we need to stop the queues before calling it if the channel's ring buffers haven't been allocated yet, but OTOH we should only stop the queues based upon the value of ring_avail, so this leads into a chicken and egg situation.  Is my observation here correct? Please correct me if I am wrong, Stephen.