diff options
author | Jakub Kicinski <kuba@kernel.org> | 2022-07-07 12:07:37 -0700 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2022-07-07 12:07:37 -0700 |
commit | 83ec88d81aa8762d4fb75f95365da6b73a38efe9 (patch) | |
tree | 193501a42e488ec81871136d19e0edb129a4a154 /net/can | |
parent | cf21b355ccb39b0de0b6a7362532bb5584c84a80 (diff) | |
parent | ef4ab3ba4e4f99b1f3af3a7b74815f59394d822e (diff) | |
download | linux-83ec88d81aa8762d4fb75f95365da6b73a38efe9.tar.gz linux-83ec88d81aa8762d4fb75f95365da6b73a38efe9.tar.bz2 linux-83ec88d81aa8762d4fb75f95365da6b73a38efe9.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
No conflicts.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/can')
-rw-r--r-- | net/can/bcm.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/net/can/bcm.c b/net/can/bcm.c index 65ee1b784a30..e60161bec850 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -100,6 +100,7 @@ static inline u64 get_u64(const struct canfd_frame *cp, int offset) struct bcm_op { struct list_head list; + struct rcu_head rcu; int ifindex; canid_t can_id; u32 flags; @@ -718,10 +719,9 @@ static struct bcm_op *bcm_find_op(struct list_head *ops, 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); @@ -732,6 +732,14 @@ static void bcm_remove_op(struct bcm_op *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) { @@ -757,6 +765,9 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh, 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 @@ -785,7 +796,6 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh, bcm_rx_handler, op); list_del(&op->list); - synchronize_rcu(); bcm_remove_op(op); return 1; /* done */ } |