From patchwork Mon Mar 5 19:41:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Eric Dumazet X-Patchwork-Id: 10259573 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A1BF96037E for ; Mon, 5 Mar 2018 19:41:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8F2E5289ED for ; Mon, 5 Mar 2018 19:41:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 81B0728A28; Mon, 5 Mar 2018 19:41:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 892BA289ED for ; Mon, 5 Mar 2018 19:41:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752586AbeCETlU (ORCPT ); Mon, 5 Mar 2018 14:41:20 -0500 Received: from mail-pl0-f65.google.com ([209.85.160.65]:44599 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751462AbeCETlP (ORCPT ); Mon, 5 Mar 2018 14:41:15 -0500 Received: by mail-pl0-f65.google.com with SMTP id 9-v6so4786675ple.11; Mon, 05 Mar 2018 11:41:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:subject:from:to:cc:date:in-reply-to:references :mime-version:content-transfer-encoding; bh=CGg8InsUQsqRKxKwGnCaJDlVJAZYemN/9jUKxrQfvLg=; b=NGM1YZYRBH+suFzCPFth2cnjEPCYHLvSJ48av9vSXtn2QAjDEcntCuoR2GFSsBWkYf g9pUeIWzDckv/k6PsrvDfwkiWoYWOBBr75gjVXGPAI+23b+cJSAf2iW8ZfqY/wYwtWK9 0XSlk0uO9T3O+f3eaZ7szLTcUC6K9tIXovUdPrjoNmVB/DI6+XSmmO85X5XcjEdRTU2Y b41bgT4M+6Gn2OJGdhRAMVCBvv6VgcBvYW7ZYC1btdP+3XCz27VdRFDYDcL3hM9BPRWE 139DE0GAFg8u2hjDCjEblPp3WxsPU6VYg+RDO1/z3ivxpP1xwEz/Fjx+EYOZA8sr9Cvx 7N+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:subject:from:to:cc:date:in-reply-to :references:mime-version:content-transfer-encoding; bh=CGg8InsUQsqRKxKwGnCaJDlVJAZYemN/9jUKxrQfvLg=; b=bGpd5gySZCapmigyD3h6YyIV+r6PL42/dmkXRTYffE+49OEwwPrLJLcnlsDfi5RJB9 hRy4kN4K4EouOJwDfpY8Q1WIg3cw3j/DL7HwW2GIm1KpzeZtFr9khqAUBs8D2HyuOmt6 T7/G4SS6C2XgHtUlC2b3gfYJzcwHJdg70lzZZiee5LrjlU9a8K/TSxLeg9/DkdwQOz4y nLxYFt3s4h7AssfQXdTVMled+gVPQmSUe6PNlBWcV2duXzw63DwraZNZtrSmC7ZWbl2m hCiXC7l4joiL9uGQTZdEcF1mTTfGgfcHPus8CDEUkir6b5Dn1ODU21vZsoA9duh3wNxw 01OQ== X-Gm-Message-State: APf1xPCJAgY8B2iErvJvnkW3LyBeZ1+mlcQAg+agMB/wqPBQUs4zLn2o DZR2h9eUFi1L4bKE9+5yibQ= X-Google-Smtp-Source: AG47ELuEuuBzMaYTLlJ7PIcTOVRXuD8bOrOKlW/kSNi6JgODYREht3bn0TIrbInZMcsJYD6MqK7mpg== X-Received: by 2002:a17:902:48c8:: with SMTP id u8-v6mr14311972plh.306.1520278874733; Mon, 05 Mar 2018 11:41:14 -0800 (PST) Received: from ?IPv6:2a00:79e1:abc:100:641:391c:2715:1239? ([2a00:79e1:abc:100:641:391c:2715:1239]) by smtp.googlemail.com with ESMTPSA id z22sm21022642pfd.158.2018.03.05.11.41.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 05 Mar 2018 11:41:13 -0800 (PST) Message-ID: <1520278873.109662.14.camel@gmail.com> Subject: [PATCH net] net: usbnet: fix potential deadlock on 32bit hosts From: Eric Dumazet To: Oliver Neukum , Marek Szyprowski Cc: 'Linux Samsung SOC' , Linux USB Mailing List , netdev@vger.kernel.org, Dean Jenkins Date: Mon, 05 Mar 2018 11:41:13 -0800 In-Reply-To: <1520276942.109662.9.camel@gmail.com> References: <1519740421.7296.6.camel@gmail.com> <1519744167.7296.8.camel@gmail.com> <1519744400.7296.10.camel@gmail.com> <1519747675.2649.3.camel@suse.com> <02679502-cf6e-8714-e879-50a922c5d976@samsung.com> <1520250367.3990.9.camel@suse.com> <1520276942.109662.9.camel@gmail.com> X-Mailer: Evolution 3.22.6-1+deb9u1 Mime-Version: 1.0 Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Dumazet Marek reported a LOCKDEP issue occurring on 32bit host, that we tracked down to the fact that usbnet could either run from soft or hard irqs. This patch adds u64_stats_update_begin_irqsave() and u64_stats_update_end_irqrestore() helpers to solve this case. [ 17.768040] ================================ [ 17.772239] WARNING: inconsistent lock state [ 17.776511] 4.16.0-rc3-next-20180227-00007-g876c53a7493c #453 Not tainted [ 17.783329] -------------------------------- [ 17.787580] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. [ 17.793607] swapper/0/0 [HC0[0]:SC1[1]:HE1:SE0] takes: [ 17.798751] (&syncp->seq#5){?.-.}, at: [<9b22e5f0>] asix_rx_fixup_internal+0x188/0x288 [ 17.806790] {IN-HARDIRQ-W} state was registered at: [ 17.811677] tx_complete+0x100/0x208 [ 17.815319] __usb_hcd_giveback_urb+0x60/0xf0 [ 17.819770] xhci_giveback_urb_in_irq+0xa8/0x240 [ 17.824469] xhci_td_cleanup+0xf4/0x16c [ 17.828367] xhci_irq+0xe74/0x2240 [ 17.831827] usb_hcd_irq+0x24/0x38 [ 17.835343] __handle_irq_event_percpu+0x98/0x510 [ 17.840111] handle_irq_event_percpu+0x1c/0x58 [ 17.844623] handle_irq_event+0x38/0x5c [ 17.848519] handle_fasteoi_irq+0xa4/0x138 [ 17.852681] generic_handle_irq+0x18/0x28 [ 17.856760] __handle_domain_irq+0x6c/0xe4 [ 17.860941] gic_handle_irq+0x54/0xa0 [ 17.864666] __irq_svc+0x70/0xb0 [ 17.867964] arch_cpu_idle+0x20/0x3c [ 17.871578] arch_cpu_idle+0x20/0x3c [ 17.875190] do_idle+0x144/0x218 [ 17.878468] cpu_startup_entry+0x18/0x1c [ 17.882454] start_kernel+0x394/0x400 [ 17.886177] irq event stamp: 161912 [ 17.889616] hardirqs last enabled at (161912): [<7bedfacf>] __netdev_alloc_skb+0xcc/0x140 [ 17.897893] hardirqs last disabled at (161911): [] __netdev_alloc_skb+0x94/0x140 [ 17.904903] exynos5-hsi2c 12ca0000.i2c: tx timeout [ 17.906116] softirqs last enabled at (161904): [<387102ff>] irq_enter+0x78/0x80 [ 17.906123] softirqs last disabled at (161905): [] irq_exit+0x134/0x158 [ 17.925722]. [ 17.925722] other info that might help us debug this: [ 17.933435] Possible unsafe locking scenario: [ 17.933435]. [ 17.940331] CPU0 [ 17.942488] ---- [ 17.944894] lock(&syncp->seq#5); [ 17.948274] [ 17.950847] lock(&syncp->seq#5); [ 17.954386]. [ 17.954386] *** DEADLOCK *** [ 17.954386]. [ 17.962422] no locks held by swapper/0/0. Fixes: c8b5d129ee29 ("net: usbnet: support 64bit stats") Signed-off-by: Eric Dumazet Reported-by: Marek Szyprowski Cc: Greg Ungerer ---  drivers/net/usb/usbnet.c       |   10 ++++++----  include/linux/u64_stats_sync.h |   22 ++++++++++++++++++++++  2 files changed, 28 insertions(+), 4 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 8a22ff67b0268a588428c61c6a6211e3c6c2a02a..d9eea8cfe6cb9a3bf8d0d4ce9198af9bccf9c757 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -315,6 +315,7 @@ static void __usbnet_status_stop_force(struct usbnet *dev) void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) { struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64); + unsigned long flags; int status; if (test_bit(EVENT_RX_PAUSED, &dev->flags)) { @@ -326,10 +327,10 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) if (skb->protocol == 0) skb->protocol = eth_type_trans (skb, dev->net); - u64_stats_update_begin(&stats64->syncp); + flags = u64_stats_update_begin_irqsave(&stats64->syncp); stats64->rx_packets++; stats64->rx_bytes += skb->len; - u64_stats_update_end(&stats64->syncp); + u64_stats_update_end_irqrestore(&stats64->syncp, flags); netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", skb->len + sizeof (struct ethhdr), skb->protocol); @@ -1248,11 +1249,12 @@ static void tx_complete (struct urb *urb) if (urb->status == 0) { struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64); + unsigned long flags; - u64_stats_update_begin(&stats64->syncp); + flags = u64_stats_update_begin_irqsave(&stats64->syncp); stats64->tx_packets += entry->packets; stats64->tx_bytes += entry->length; - u64_stats_update_end(&stats64->syncp); + u64_stats_update_end_irqrestore(&stats64->syncp, flags); } else { dev->net->stats.tx_errors++; diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h index 5bdbd9f49395f883ca2dc5aa0d7bbde11f379063..07ee0f84a46caa9e2b1c446f96009f63b3b99f50 100644 --- a/include/linux/u64_stats_sync.h +++ b/include/linux/u64_stats_sync.h @@ -90,6 +90,28 @@ static inline void u64_stats_update_end(struct u64_stats_sync *syncp) #endif } +static inline unsigned long +u64_stats_update_begin_irqsave(struct u64_stats_sync *syncp) +{ + unsigned long flags = 0; + +#if BITS_PER_LONG==32 && defined(CONFIG_SMP) + local_irq_save(flags); + write_seqcount_begin(&syncp->seq); +#endif + return flags; +} + +static inline void +u64_stats_update_end_irqrestore(struct u64_stats_sync *syncp, + unsigned long flags) +{ +#if BITS_PER_LONG==32 && defined(CONFIG_SMP) + write_seqcount_end(&syncp->seq); + local_irq_restore(flags); +#endif +} + static inline void u64_stats_update_begin_raw(struct u64_stats_sync *syncp) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP)