Skip to content

Commit d3b58c4

Browse files
hartkoppmarckleinebudde
authored andcommitted
can: replace timestamp as unique skb attribute
Commit 514ac99 "can: fix multiple delivery of a single CAN frame for overlapping CAN filters" requires the skb->tstamp to be set to check for identical CAN skbs. Without timestamping to be required by user space applications this timestamp was not generated which lead to commit 36c0124 "can: fix loss of CAN frames in raw_rcv" - which forces the timestamp to be set in all CAN related skbuffs by introducing several __net_timestamp() calls. This forces e.g. out of tree drivers which are not using alloc_can{,fd}_skb() to add __net_timestamp() after skbuff creation to prevent the frame loss fixed in mainline Linux. This patch removes the timestamp dependency and uses an atomic counter to create an unique identifier together with the skbuff pointer. Btw: the new skbcnt element introduced in struct can_skb_priv has to be initialized with zero in out-of-tree drivers which are not using alloc_can{,fd}_skb() too. Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
1 parent 2acb5c3 commit d3b58c4

File tree

7 files changed

+18
-17
lines changed

7 files changed

+18
-17
lines changed

drivers/net/can/dev.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,6 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
440440
struct can_frame *cf = (struct can_frame *)skb->data;
441441
u8 dlc = cf->can_dlc;
442442

443-
if (!(skb->tstamp.tv64))
444-
__net_timestamp(skb);
445-
446443
netif_rx(priv->echo_skb[idx]);
447444
priv->echo_skb[idx] = NULL;
448445

@@ -578,7 +575,6 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
578575
if (unlikely(!skb))
579576
return NULL;
580577

581-
__net_timestamp(skb);
582578
skb->protocol = htons(ETH_P_CAN);
583579
skb->pkt_type = PACKET_BROADCAST;
584580
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -589,6 +585,7 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
589585

590586
can_skb_reserve(skb);
591587
can_skb_prv(skb)->ifindex = dev->ifindex;
588+
can_skb_prv(skb)->skbcnt = 0;
592589

593590
*cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
594591
memset(*cf, 0, sizeof(struct can_frame));
@@ -607,7 +604,6 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev,
607604
if (unlikely(!skb))
608605
return NULL;
609606

610-
__net_timestamp(skb);
611607
skb->protocol = htons(ETH_P_CANFD);
612608
skb->pkt_type = PACKET_BROADCAST;
613609
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -618,6 +614,7 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev,
618614

619615
can_skb_reserve(skb);
620616
can_skb_prv(skb)->ifindex = dev->ifindex;
617+
can_skb_prv(skb)->skbcnt = 0;
621618

622619
*cfd = (struct canfd_frame *)skb_put(skb, sizeof(struct canfd_frame));
623620
memset(*cfd, 0, sizeof(struct canfd_frame));

drivers/net/can/slcan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,14 @@ static void slc_bump(struct slcan *sl)
207207
if (!skb)
208208
return;
209209

210-
__net_timestamp(skb);
211210
skb->dev = sl->dev;
212211
skb->protocol = htons(ETH_P_CAN);
213212
skb->pkt_type = PACKET_BROADCAST;
214213
skb->ip_summed = CHECKSUM_UNNECESSARY;
215214

216215
can_skb_reserve(skb);
217216
can_skb_prv(skb)->ifindex = sl->dev->ifindex;
217+
can_skb_prv(skb)->skbcnt = 0;
218218

219219
memcpy(skb_put(skb, sizeof(struct can_frame)),
220220
&cf, sizeof(struct can_frame));

drivers/net/can/vcan.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,6 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
7878
skb->dev = dev;
7979
skb->ip_summed = CHECKSUM_UNNECESSARY;
8080

81-
if (!(skb->tstamp.tv64))
82-
__net_timestamp(skb);
83-
8481
netif_rx_ni(skb);
8582
}
8683

include/linux/can/skb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
/**
2828
* struct can_skb_priv - private additional data inside CAN sk_buffs
2929
* @ifindex: ifindex of the first interface the CAN frame appeared on
30+
* @skbcnt: atomic counter to have an unique id together with skb pointer
3031
* @cf: align to the following CAN frame at skb->data
3132
*/
3233
struct can_skb_priv {
3334
int ifindex;
35+
int skbcnt;
3436
struct can_frame cf[0];
3537
};
3638

net/can/af_can.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ struct timer_list can_stattimer; /* timer for statistics update */
8989
struct s_stats can_stats; /* packet statistics */
9090
struct s_pstats can_pstats; /* receive list statistics */
9191

92+
static atomic_t skbcounter = ATOMIC_INIT(0);
93+
9294
/*
9395
* af_can socket functions
9496
*/
@@ -310,12 +312,8 @@ int can_send(struct sk_buff *skb, int loop)
310312
return err;
311313
}
312314

313-
if (newskb) {
314-
if (!(newskb->tstamp.tv64))
315-
__net_timestamp(newskb);
316-
315+
if (newskb)
317316
netif_rx_ni(newskb);
318-
}
319317

320318
/* update statistics */
321319
can_stats.tx_frames++;
@@ -683,6 +681,10 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev)
683681
can_stats.rx_frames++;
684682
can_stats.rx_frames_delta++;
685683

684+
/* create non-zero unique skb identifier together with *skb */
685+
while (!(can_skb_prv(skb)->skbcnt))
686+
can_skb_prv(skb)->skbcnt = atomic_inc_return(&skbcounter);
687+
686688
rcu_read_lock();
687689

688690
/* deliver the packet to sockets listening on all devices */

net/can/bcm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ static void bcm_can_tx(struct bcm_op *op)
261261

262262
can_skb_reserve(skb);
263263
can_skb_prv(skb)->ifindex = dev->ifindex;
264+
can_skb_prv(skb)->skbcnt = 0;
264265

265266
memcpy(skb_put(skb, CFSIZ), cf, CFSIZ);
266267

@@ -1217,6 +1218,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
12171218
}
12181219

12191220
can_skb_prv(skb)->ifindex = dev->ifindex;
1221+
can_skb_prv(skb)->skbcnt = 0;
12201222
skb->dev = dev;
12211223
can_skb_set_owner(skb, sk);
12221224
err = can_send(skb, 1); /* send with loopback */

net/can/raw.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ MODULE_ALIAS("can-proto-1");
7575
*/
7676

7777
struct uniqframe {
78-
ktime_t tstamp;
78+
int skbcnt;
7979
const struct sk_buff *skb;
8080
unsigned int join_rx_count;
8181
};
@@ -133,7 +133,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
133133

134134
/* eliminate multiple filter matches for the same skb */
135135
if (this_cpu_ptr(ro->uniq)->skb == oskb &&
136-
ktime_equal(this_cpu_ptr(ro->uniq)->tstamp, oskb->tstamp)) {
136+
this_cpu_ptr(ro->uniq)->skbcnt == can_skb_prv(oskb)->skbcnt) {
137137
if (ro->join_filters) {
138138
this_cpu_inc(ro->uniq->join_rx_count);
139139
/* drop frame until all enabled filters matched */
@@ -144,7 +144,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
144144
}
145145
} else {
146146
this_cpu_ptr(ro->uniq)->skb = oskb;
147-
this_cpu_ptr(ro->uniq)->tstamp = oskb->tstamp;
147+
this_cpu_ptr(ro->uniq)->skbcnt = can_skb_prv(oskb)->skbcnt;
148148
this_cpu_ptr(ro->uniq)->join_rx_count = 1;
149149
/* drop first frame to check all enabled filters? */
150150
if (ro->join_filters && ro->count > 1)
@@ -749,6 +749,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
749749

750750
can_skb_reserve(skb);
751751
can_skb_prv(skb)->ifindex = dev->ifindex;
752+
can_skb_prv(skb)->skbcnt = 0;
752753

753754
err = memcpy_from_msg(skb_put(skb, size), msg, size);
754755
if (err < 0)

0 commit comments

Comments
 (0)