提交 28c7164b 编写于 作者: V Vincent Mailhol 提交者: Zheng Zengkai

can: gs_usb: change active_channels's type from atomic_t to u8

stable inclusion
from stable-v5.10.104
commit 43eaf1b17845a25e3e3a7d3f09c2f5ebd4a9d607
bugzilla: https://gitee.com/openeuler/kernel/issues/I56XAC

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=43eaf1b17845a25e3e3a7d3f09c2f5ebd4a9d607

--------------------------------

commit 035b0fcf upstream.

The driver uses an atomic_t variable: gs_usb:active_channels to keep
track of the number of opened channels in order to only allocate
memory for the URBs when this count changes from zero to one.

However, the driver does not decrement the counter when an error
occurs in gs_can_open(). This issue is fixed by changing the type from
atomic_t to u8 and by simplifying the logic accordingly.

It is safe to use an u8 here because the network stack big kernel lock
(a.k.a. rtnl_mutex) is being hold. For details, please refer to [1].

[1] https://lore.kernel.org/linux-can/CAMZ6Rq+sHpiw34ijPsmp7vbUpDtJwvVtdV7CvRZJsLixjAFfrg@mail.gmail.com/T/#t

Fixes: d08e973a ("can: gs_usb: Added support for the GS_USB CAN devices")
Link: https://lore.kernel.org/all/20220214234814.1321599-1-mailhol.vincent@wanadoo.frSigned-off-by: NVincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NYu Liao <liaoyu15@huawei.com>
Reviewed-by: NWei Li <liwei391@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 b93ad72c
...@@ -190,8 +190,8 @@ struct gs_can { ...@@ -190,8 +190,8 @@ struct gs_can {
struct gs_usb { struct gs_usb {
struct gs_can *canch[GS_MAX_INTF]; struct gs_can *canch[GS_MAX_INTF];
struct usb_anchor rx_submitted; struct usb_anchor rx_submitted;
atomic_t active_channels;
struct usb_device *udev; struct usb_device *udev;
u8 active_channels;
}; };
/* 'allocate' a tx context. /* 'allocate' a tx context.
...@@ -588,7 +588,7 @@ static int gs_can_open(struct net_device *netdev) ...@@ -588,7 +588,7 @@ static int gs_can_open(struct net_device *netdev)
if (rc) if (rc)
return rc; return rc;
if (atomic_add_return(1, &parent->active_channels) == 1) { if (!parent->active_channels) {
for (i = 0; i < GS_MAX_RX_URBS; i++) { for (i = 0; i < GS_MAX_RX_URBS; i++) {
struct urb *urb; struct urb *urb;
u8 *buf; u8 *buf;
...@@ -689,6 +689,7 @@ static int gs_can_open(struct net_device *netdev) ...@@ -689,6 +689,7 @@ static int gs_can_open(struct net_device *netdev)
dev->can.state = CAN_STATE_ERROR_ACTIVE; dev->can.state = CAN_STATE_ERROR_ACTIVE;
parent->active_channels++;
if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
netif_start_queue(netdev); netif_start_queue(netdev);
...@@ -704,7 +705,8 @@ static int gs_can_close(struct net_device *netdev) ...@@ -704,7 +705,8 @@ static int gs_can_close(struct net_device *netdev)
netif_stop_queue(netdev); netif_stop_queue(netdev);
/* Stop polling */ /* Stop polling */
if (atomic_dec_and_test(&parent->active_channels)) parent->active_channels--;
if (!parent->active_channels)
usb_kill_anchored_urbs(&parent->rx_submitted); usb_kill_anchored_urbs(&parent->rx_submitted);
/* Stop sending URBs */ /* Stop sending URBs */
...@@ -983,8 +985,6 @@ static int gs_usb_probe(struct usb_interface *intf, ...@@ -983,8 +985,6 @@ static int gs_usb_probe(struct usb_interface *intf,
init_usb_anchor(&dev->rx_submitted); init_usb_anchor(&dev->rx_submitted);
atomic_set(&dev->active_channels, 0);
usb_set_intfdata(intf, dev); usb_set_intfdata(intf, dev);
dev->udev = interface_to_usbdev(intf); dev->udev = interface_to_usbdev(intf);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册