Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp269549img; Mon, 18 Mar 2019 02:43:52 -0700 (PDT) X-Google-Smtp-Source: APXvYqwXr30CMjbv1bYO2HvbwaERBozj4V4+VLHbqE0NqSmaORPtQ0uztzxwT806gvEqvM8mzZrH X-Received: by 2002:a65:4181:: with SMTP id a1mr16882352pgq.100.1552902232477; Mon, 18 Mar 2019 02:43:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552902232; cv=none; d=google.com; s=arc-20160816; b=eCYwQCGPQkuPqN6rrZhJLBT9SuDmUOC4vSWs9cq/dlSMgR9yprHJJYlw5bk3PwofAt Yy0JUynsGrMpmvZk5dUMv0XFvn5PMhnVKLOmVl9TdPdJZgpUQ/c1Xh6dMNjMVyRo10nh NwUDG83wwNmSKVlBocwRUwM8hO9taOS/TFX/N51X27KvjpAL4Oir5jDvLqLknPN73oAh LxjNVyFq2s27f33F3A9j4I+qn2T4lQWsLAMABrMmmJvxPGrdhO9T0/doSCeYHceynnUF RMXUUJYVm7Kskc+1/QJoOML9YhCSBWg4TTohN8dGxqdRJV3VZNNEy8NFJxzRy/ggtIn9 n9fA== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=UWRkBM/5kzz+pc3gjNZ+8AOvL1cX015U6kugs0sE9Nk=; b=tzw4FvZfF2iZ5iflsvXrgBR2+GJOwc033Ab2NoKUrEEodXdmb2zpkzBZSiequkhJfO K0qUJhGjXGcd5z9mm8L6HG5E4Sw97dDM/SdINBM2Ybi2iolrUBJFUXTFFr8FkN5/0hTV VLBrjFSZcA9wruxoQUQF7X3NJmJVySW2YU3yPIKLlzsUHCsjf9g4yOuyk7v+Rnq5usO8 OJ10OWuwvNZ1WEfe0gQ3YEbhXbgrNi4oifmbiZaboIgOceS3Ro7+GCSCt+arQb0TxCfd sAKw4W0P8SCkOMLmZtdz6WBybSjjW371DfzlfDdLtIDdAgPfAK0Mj5AMjbYWh/PUvCVm cdzw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=IrfCNLno; 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 p17si8698423pgb.329.2019.03.18.02.43.37; Mon, 18 Mar 2019 02:43:52 -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=IrfCNLno; 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 S1728817AbfCRJdJ (ORCPT + 99 others); Mon, 18 Mar 2019 05:33:09 -0400 Received: from mail.kernel.org ([198.145.29.99]:41218 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728814AbfCRJdG (ORCPT ); Mon, 18 Mar 2019 05:33:06 -0400 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (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 1A24A2083D; Mon, 18 Mar 2019 09:33:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1552901584; bh=5fYn1dsJRCI8f1R8ZZ9ksM5ksv+0xOCJLYy8ZlOwqdI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IrfCNLnoA+WBa2MZDvWtBq+wSdVDSFKqGJG4J9P6p0GQZNCsiD2Z0vqw9ATUjM2V1 btwDojQhKdJoeyOfcAklOROu1yESxiLOOVtSSwhhtRF7srha5J/6aMb2YQ4EE/ztQn llb6Q1rn1IEwRIYM6dYxGZp9p2WQrQryomSeEcoI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Bryan Whitehead , "David S. Miller" Subject: [PATCH 4.19 05/52] lan743x: Fix RX Kernel Panic Date: Mon, 18 Mar 2019 10:25:02 +0100 Message-Id: <20190318084014.181465141@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190318084013.532280682@linuxfoundation.org> References: <20190318084013.532280682@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Bryan Whitehead [ Upstream commit dd9d9f5907bb475f8b1796c47d4ecc7fb9b72136 ] It has been noticed that running the speed test at www.speedtest.net occasionally causes a kernel panic. Investigation revealed that under this test RX buffer allocation sometimes fails and returns NULL. But the lan743x driver did not handle this case. This patch fixes this issue by attempting to allocate a buffer before sending the new rx packet to the OS. If the allocation fails then the new rx packet is dropped and the existing buffer is reused in the DMA ring. Updates for v2: Additional 2 locations where allocation was not checked, has been changed to reuse existing buffer. Fixes: 23f0703c125b ("lan743x: Add main source files for new lan743x driver") Signed-off-by: Bryan Whitehead Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/microchip/lan743x_main.c | 46 ++++++++++++++++++-------- 1 file changed, 32 insertions(+), 14 deletions(-) --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c @@ -1905,7 +1905,17 @@ static int lan743x_rx_next_index(struct return ((++index) % rx->ring_size); } -static int lan743x_rx_allocate_ring_element(struct lan743x_rx *rx, int index) +static struct sk_buff *lan743x_rx_allocate_skb(struct lan743x_rx *rx) +{ + int length = 0; + + length = (LAN743X_MAX_FRAME_SIZE + ETH_HLEN + 4 + RX_HEAD_PADDING); + return __netdev_alloc_skb(rx->adapter->netdev, + length, GFP_ATOMIC | GFP_DMA); +} + +static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index, + struct sk_buff *skb) { struct lan743x_rx_buffer_info *buffer_info; struct lan743x_rx_descriptor *descriptor; @@ -1914,9 +1924,7 @@ static int lan743x_rx_allocate_ring_elem length = (LAN743X_MAX_FRAME_SIZE + ETH_HLEN + 4 + RX_HEAD_PADDING); descriptor = &rx->ring_cpu_ptr[index]; buffer_info = &rx->buffer_info[index]; - buffer_info->skb = __netdev_alloc_skb(rx->adapter->netdev, - length, - GFP_ATOMIC | GFP_DMA); + buffer_info->skb = skb; if (!(buffer_info->skb)) return -ENOMEM; buffer_info->dma_ptr = dma_map_single(&rx->adapter->pdev->dev, @@ -2063,8 +2071,19 @@ static int lan743x_rx_process_packet(str /* packet is available */ if (first_index == last_index) { /* single buffer packet */ + struct sk_buff *new_skb = NULL; int packet_length; + new_skb = lan743x_rx_allocate_skb(rx); + if (!new_skb) { + /* failed to allocate next skb. + * Memory is very low. + * Drop this packet and reuse buffer. + */ + lan743x_rx_reuse_ring_element(rx, first_index); + goto process_extension; + } + buffer_info = &rx->buffer_info[first_index]; skb = buffer_info->skb; descriptor = &rx->ring_cpu_ptr[first_index]; @@ -2084,7 +2103,7 @@ static int lan743x_rx_process_packet(str skb_put(skb, packet_length - 4); skb->protocol = eth_type_trans(skb, rx->adapter->netdev); - lan743x_rx_allocate_ring_element(rx, first_index); + lan743x_rx_init_ring_element(rx, first_index, new_skb); } else { int index = first_index; @@ -2097,26 +2116,23 @@ static int lan743x_rx_process_packet(str if (first_index <= last_index) { while ((index >= first_index) && (index <= last_index)) { - lan743x_rx_release_ring_element(rx, - index); - lan743x_rx_allocate_ring_element(rx, - index); + lan743x_rx_reuse_ring_element(rx, + index); index = lan743x_rx_next_index(rx, index); } } else { while ((index >= first_index) || (index <= last_index)) { - lan743x_rx_release_ring_element(rx, - index); - lan743x_rx_allocate_ring_element(rx, - index); + lan743x_rx_reuse_ring_element(rx, + index); index = lan743x_rx_next_index(rx, index); } } } +process_extension: if (extension_index >= 0) { descriptor = &rx->ring_cpu_ptr[extension_index]; buffer_info = &rx->buffer_info[extension_index]; @@ -2293,7 +2309,9 @@ static int lan743x_rx_ring_init(struct l rx->last_head = 0; for (index = 0; index < rx->ring_size; index++) { - ret = lan743x_rx_allocate_ring_element(rx, index); + struct sk_buff *new_skb = lan743x_rx_allocate_skb(rx); + + ret = lan743x_rx_init_ring_element(rx, index, new_skb); if (ret) goto cleanup; }