Skip to content

Commit

Permalink
can: gs_usb: change active_channels's type from atomic_t to u8
Browse files Browse the repository at this point in the history
commit 035b0fc 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: d08e973 ("can: gs_usb: Added support for the GS_USB CAN devices")
Link: https://lore.kernel.org/all/20220214234814.1321599-1-mailhol.vincent@wanadoo.fr
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
vincent-mailhol authored and gregkh committed Mar 8, 2022
1 parent daaed6c commit 43eaf1b
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions drivers/net/can/usb/gs_usb.c
Expand Up @@ -190,8 +190,8 @@ struct gs_can {
struct gs_usb {
struct gs_can *canch[GS_MAX_INTF];
struct usb_anchor rx_submitted;
atomic_t active_channels;
struct usb_device *udev;
u8 active_channels;
};

/* 'allocate' a tx context.
Expand Down Expand Up @@ -588,7 +588,7 @@ static int gs_can_open(struct net_device *netdev)
if (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++) {
struct urb *urb;
u8 *buf;
Expand Down Expand Up @@ -689,6 +689,7 @@ static int gs_can_open(struct net_device *netdev)

dev->can.state = CAN_STATE_ERROR_ACTIVE;

parent->active_channels++;
if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
netif_start_queue(netdev);

Expand All @@ -704,7 +705,8 @@ static int gs_can_close(struct net_device *netdev)
netif_stop_queue(netdev);

/* Stop polling */
if (atomic_dec_and_test(&parent->active_channels))
parent->active_channels--;
if (!parent->active_channels)
usb_kill_anchored_urbs(&parent->rx_submitted);

/* Stop sending URBs */
Expand Down Expand Up @@ -983,8 +985,6 @@ static int gs_usb_probe(struct usb_interface *intf,

init_usb_anchor(&dev->rx_submitted);

atomic_set(&dev->active_channels, 0);

usb_set_intfdata(intf, dev);
dev->udev = interface_to_usbdev(intf);

Expand Down

0 comments on commit 43eaf1b

Please sign in to comment.