From: Greg Kroah-Hartman Date: Fri, 8 Jul 2022 11:10:12 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v4.9.323~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60edf6acb4e3ee893dfda7c3936b7ad511fd64fe;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: can-bcm-use-call_rcu-instead-of-costly-synchronize_rcu.patch can-grcan-grcan_probe-remove-extra-of_node_get.patch can-gs_usb-gs_usb_open-close-fix-memory-leak.patch --- diff --git a/queue-4.19/can-bcm-use-call_rcu-instead-of-costly-synchronize_rcu.patch b/queue-4.19/can-bcm-use-call_rcu-instead-of-costly-synchronize_rcu.patch new file mode 100644 index 00000000000..773929d6326 --- /dev/null +++ b/queue-4.19/can-bcm-use-call_rcu-instead-of-costly-synchronize_rcu.patch @@ -0,0 +1,97 @@ +From f1b4e32aca0811aa011c76e5d6cf2fa19224b386 Mon Sep 17 00:00:00 2001 +From: Oliver Hartkopp +Date: Fri, 20 May 2022 20:32:39 +0200 +Subject: can: bcm: use call_rcu() instead of costly synchronize_rcu() + +From: Oliver Hartkopp + +commit f1b4e32aca0811aa011c76e5d6cf2fa19224b386 upstream. + +In commit d5f9023fa61e ("can: bcm: delay release of struct bcm_op +after synchronize_rcu()") Thadeu Lima de Souza Cascardo introduced two +synchronize_rcu() calls in bcm_release() (only once at socket close) +and in bcm_delete_rx_op() (called on removal of each single bcm_op). + +Unfortunately this slow removal of the bcm_op's affects user space +applications like cansniffer where the modification of a filter +removes 2048 bcm_op's which blocks the cansniffer application for +40(!) seconds. + +In commit 181d4447905d ("can: gw: use call_rcu() instead of costly +synchronize_rcu()") Eric Dumazet replaced the synchronize_rcu() calls +with several call_rcu()'s to safely remove the data structures after +the removal of CAN ID subscriptions with can_rx_unregister() calls. + +This patch adopts Erics approach for the can-bcm which should be +applicable since the removal of tasklet_kill() in bcm_remove_op() and +the introduction of the HRTIMER_MODE_SOFT timer handling in Linux 5.4. + +Fixes: d5f9023fa61e ("can: bcm: delay release of struct bcm_op after synchronize_rcu()") # >= 5.4 +Link: https://lore.kernel.org/all/20220520183239.19111-1-socketcan@hartkopp.net +Cc: stable@vger.kernel.org +Cc: Eric Dumazet +Cc: Norbert Slusarek +Cc: Thadeu Lima de Souza Cascardo +Signed-off-by: Oliver Hartkopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + net/can/bcm.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/net/can/bcm.c ++++ b/net/can/bcm.c +@@ -99,6 +99,7 @@ static inline u64 get_u64(const struct c + + struct bcm_op { + struct list_head list; ++ struct rcu_head rcu; + int ifindex; + canid_t can_id; + u32 flags; +@@ -717,10 +718,9 @@ static struct bcm_op *bcm_find_op(struct + return NULL; + } + +-static void bcm_remove_op(struct bcm_op *op) ++static void bcm_free_op_rcu(struct rcu_head *rcu_head) + { +- hrtimer_cancel(&op->timer); +- hrtimer_cancel(&op->thrtimer); ++ struct bcm_op *op = container_of(rcu_head, struct bcm_op, rcu); + + if ((op->frames) && (op->frames != &op->sframe)) + kfree(op->frames); +@@ -731,6 +731,14 @@ static void bcm_remove_op(struct bcm_op + kfree(op); + } + ++static void bcm_remove_op(struct bcm_op *op) ++{ ++ hrtimer_cancel(&op->timer); ++ hrtimer_cancel(&op->thrtimer); ++ ++ call_rcu(&op->rcu, bcm_free_op_rcu); ++} ++ + static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op) + { + if (op->rx_reg_dev == dev) { +@@ -756,6 +764,9 @@ static int bcm_delete_rx_op(struct list_ + if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) && + (op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) { + ++ /* disable automatic timer on frame reception */ ++ op->flags |= RX_NO_AUTOTIMER; ++ + /* + * Don't care if we're bound or not (due to netdev + * problems) can_rx_unregister() is always a save +@@ -784,7 +795,6 @@ static int bcm_delete_rx_op(struct list_ + bcm_rx_handler, op); + + list_del(&op->list); +- synchronize_rcu(); + bcm_remove_op(op); + return 1; /* done */ + } diff --git a/queue-4.19/can-grcan-grcan_probe-remove-extra-of_node_get.patch b/queue-4.19/can-grcan-grcan_probe-remove-extra-of_node_get.patch new file mode 100644 index 00000000000..710a42d4e05 --- /dev/null +++ b/queue-4.19/can-grcan-grcan_probe-remove-extra-of_node_get.patch @@ -0,0 +1,33 @@ +From 562fed945ea482833667f85496eeda766d511386 Mon Sep 17 00:00:00 2001 +From: Liang He +Date: Sun, 19 Jun 2022 15:02:57 +0800 +Subject: can: grcan: grcan_probe(): remove extra of_node_get() + +From: Liang He + +commit 562fed945ea482833667f85496eeda766d511386 upstream. + +In grcan_probe(), of_find_node_by_path() has already increased the +refcount. There is no need to call of_node_get() again, so remove it. + +Link: https://lore.kernel.org/all/20220619070257.4067022-1-windhl@126.com +Fixes: 1e93ed26acf0 ("can: grcan: grcan_probe(): fix broken system id check for errata workaround needs") +Cc: stable@vger.kernel.org # v5.18 +Cc: Andreas Larsson +Signed-off-by: Liang He +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/grcan.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/can/grcan.c ++++ b/drivers/net/can/grcan.c +@@ -1664,7 +1664,6 @@ static int grcan_probe(struct platform_d + */ + sysid_parent = of_find_node_by_path("/ambapp0"); + if (sysid_parent) { +- of_node_get(sysid_parent); + err = of_property_read_u32(sysid_parent, "systemid", &sysid); + if (!err && ((sysid & GRLIB_VERSION_MASK) >= + GRCAN_TXBUG_SAFE_GRLIB_VERSION)) diff --git a/queue-4.19/can-gs_usb-gs_usb_open-close-fix-memory-leak.patch b/queue-4.19/can-gs_usb-gs_usb_open-close-fix-memory-leak.patch new file mode 100644 index 00000000000..d9074a9747e --- /dev/null +++ b/queue-4.19/can-gs_usb-gs_usb_open-close-fix-memory-leak.patch @@ -0,0 +1,113 @@ +From 2bda24ef95c0311ab93bda00db40486acf30bd0a Mon Sep 17 00:00:00 2001 +From: Rhett Aultman +Date: Sun, 3 Jul 2022 19:33:06 +0200 +Subject: can: gs_usb: gs_usb_open/close(): fix memory leak + +From: Rhett Aultman + +commit 2bda24ef95c0311ab93bda00db40486acf30bd0a upstream. + +The gs_usb driver appears to suffer from a malady common to many USB +CAN adapter drivers in that it performs usb_alloc_coherent() to +allocate a number of USB request blocks (URBs) for RX, and then later +relies on usb_kill_anchored_urbs() to free them, but this doesn't +actually free them. As a result, this may be leaking DMA memory that's +been used by the driver. + +This commit is an adaptation of the techniques found in the esd_usb2 +driver where a similar design pattern led to a memory leak. It +explicitly frees the RX URBs and their DMA memory via a call to +usb_free_coherent(). Since the RX URBs were allocated in the +gs_can_open(), we remove them in gs_can_close() rather than in the +disconnect function as was done in esd_usb2. + +For more information, see the 928150fad41b ("can: esd_usb2: fix memory +leak"). + +Link: https://lore.kernel.org/all/alpine.DEB.2.22.394.2206031547001.1630869@thelappy +Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") +Cc: stable@vger.kernel.org +Signed-off-by: Rhett Aultman +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/gs_usb.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -192,6 +192,8 @@ struct gs_can { + + struct usb_anchor tx_submitted; + atomic_t active_tx_urbs; ++ void *rxbuf[GS_MAX_RX_URBS]; ++ dma_addr_t rxbuf_dma[GS_MAX_RX_URBS]; + }; + + /* usb interface struct */ +@@ -600,6 +602,7 @@ static int gs_can_open(struct net_device + for (i = 0; i < GS_MAX_RX_URBS; i++) { + struct urb *urb; + u8 *buf; ++ dma_addr_t buf_dma; + + /* alloc rx urb */ + urb = usb_alloc_urb(0, GFP_KERNEL); +@@ -610,7 +613,7 @@ static int gs_can_open(struct net_device + buf = usb_alloc_coherent(dev->udev, + sizeof(struct gs_host_frame), + GFP_KERNEL, +- &urb->transfer_dma); ++ &buf_dma); + if (!buf) { + netdev_err(netdev, + "No memory left for USB buffer\n"); +@@ -618,6 +621,8 @@ static int gs_can_open(struct net_device + return -ENOMEM; + } + ++ urb->transfer_dma = buf_dma; ++ + /* fill, anchor, and submit rx urb */ + usb_fill_bulk_urb(urb, + dev->udev, +@@ -641,10 +646,17 @@ static int gs_can_open(struct net_device + rc); + + usb_unanchor_urb(urb); ++ usb_free_coherent(dev->udev, ++ sizeof(struct gs_host_frame), ++ buf, ++ buf_dma); + usb_free_urb(urb); + break; + } + ++ dev->rxbuf[i] = buf; ++ dev->rxbuf_dma[i] = buf_dma; ++ + /* Drop reference, + * USB core will take care of freeing it + */ +@@ -709,13 +721,20 @@ static int gs_can_close(struct net_devic + int rc; + struct gs_can *dev = netdev_priv(netdev); + struct gs_usb *parent = dev->parent; ++ unsigned int i; + + netif_stop_queue(netdev); + + /* Stop polling */ + parent->active_channels--; +- if (!parent->active_channels) ++ if (!parent->active_channels) { + usb_kill_anchored_urbs(&parent->rx_submitted); ++ for (i = 0; i < GS_MAX_RX_URBS; i++) ++ usb_free_coherent(dev->udev, ++ sizeof(struct gs_host_frame), ++ dev->rxbuf[i], ++ dev->rxbuf_dma[i]); ++ } + + /* Stop sending URBs */ + usb_kill_anchored_urbs(&dev->tx_submitted); diff --git a/queue-4.19/series b/queue-4.19/series index 48cefe5d057..e3b34df9e57 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -1,2 +1,5 @@ esp-limit-skb_page_frag_refill-use-to-a-single-page.patch mm-slub-add-missing-tid-updates-on-slab-deactivation.patch +can-bcm-use-call_rcu-instead-of-costly-synchronize_rcu.patch +can-grcan-grcan_probe-remove-extra-of_node_get.patch +can-gs_usb-gs_usb_open-close-fix-memory-leak.patch