* [PATCH 1/8] can: rcar_can: fix IRQ check [not found] <1436728691-1145-1-git-send-email-mkl@pengutronix.de> @ 2015-07-12 19:18 ` Marc Kleine-Budde 2015-07-12 19:18 ` [PATCH 6/8] can: c_can: Fix default pinmux glitch at init Marc Kleine-Budde ` (2 subsequent siblings) 3 siblings, 0 replies; 6+ messages in thread From: Marc Kleine-Budde @ 2015-07-12 19:18 UTC (permalink / raw) To: netdev Cc: davem, linux-can, kernel, Sergei Shtylyov, linux-stable, Marc Kleine-Budde From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> rcar_can_probe() regards 0 as a wrong IRQ #, despite platform_get_irq() that it calls returns negative error code in that case. This leads to the following being printed to the console when attempting to open the device: error requesting interrupt fffffffa because rcar_can_open() calls request_irq() with a negative IRQ #, and that function naturally fails with -EINVAL. Check for the negative error codes instead and propagate them upstream instead of just returning -ENODEV. Fixes: fd1159318e55 ("can: add Renesas R-Car CAN driver") Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> --- drivers/net/can/rcar_can.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c index 7deb80dcbe8c..93017c09cfc3 100644 --- a/drivers/net/can/rcar_can.c +++ b/drivers/net/can/rcar_can.c @@ -758,8 +758,9 @@ static int rcar_can_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (!irq) { + if (irq < 0) { dev_err(&pdev->dev, "No IRQ resource\n"); + err = irq; goto fail; } -- 2.1.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6/8] can: c_can: Fix default pinmux glitch at init [not found] <1436728691-1145-1-git-send-email-mkl@pengutronix.de> 2015-07-12 19:18 ` [PATCH 1/8] can: rcar_can: fix IRQ check Marc Kleine-Budde @ 2015-07-12 19:18 ` Marc Kleine-Budde 2015-07-12 19:18 ` [PATCH 7/8] ARM: dts: dra7x-evm: Prevent glitch on DCAN1 pinmux Marc Kleine-Budde 2015-07-12 19:18 ` [PATCH 8/8] can: replace timestamp as unique skb attribute Marc Kleine-Budde 3 siblings, 0 replies; 6+ messages in thread From: Marc Kleine-Budde @ 2015-07-12 19:18 UTC (permalink / raw) To: netdev Cc: davem, linux-can, kernel, J.D. Schroeder, Roger Quadros, linux-stable, Marc Kleine-Budde From: "J.D. Schroeder" <jay.schroeder@garmin.com> The previous change 3973c526ae9c (net: can: c_can: Disable pins when CAN interface is down) causes a slight glitch on the pinctrl settings when used. Since commit ab78029 (drivers/pinctrl: grab default handles from device core), the device core will automatically set the default pins. This causes the pins to be momentarily set to the default and then to the sleep state in register_c_can_dev(). By adding an optional "enable" state, boards can set the default pin state to be disabled and avoid the glitch when the switch from default to sleep first occurs. If the "enable" state is not available c_can_pinctrl_select_state() falls back to using the "default" pinctrl state. [Roger Q] - Forward port to v4.2 and use pinctrl_get_select(). Signed-off-by: J.D. Schroeder <jay.schroeder@garmin.com> Signed-off-by: Roger Quadros <rogerq@ti.com> Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> --- drivers/net/can/c_can/c_can.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 041525d2595c..5d214d135332 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -592,6 +592,7 @@ static int c_can_start(struct net_device *dev) { struct c_can_priv *priv = netdev_priv(dev); int err; + struct pinctrl *p; /* basic c_can configuration */ err = c_can_chip_config(dev); @@ -604,8 +605,13 @@ static int c_can_start(struct net_device *dev) priv->can.state = CAN_STATE_ERROR_ACTIVE; - /* activate pins */ - pinctrl_pm_select_default_state(dev->dev.parent); + /* Attempt to use "active" if available else use "default" */ + p = pinctrl_get_select(priv->device, "active"); + if (!IS_ERR(p)) + pinctrl_put(p); + else + pinctrl_pm_select_default_state(priv->device); + return 0; } -- 2.1.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 7/8] ARM: dts: dra7x-evm: Prevent glitch on DCAN1 pinmux [not found] <1436728691-1145-1-git-send-email-mkl@pengutronix.de> 2015-07-12 19:18 ` [PATCH 1/8] can: rcar_can: fix IRQ check Marc Kleine-Budde 2015-07-12 19:18 ` [PATCH 6/8] can: c_can: Fix default pinmux glitch at init Marc Kleine-Budde @ 2015-07-12 19:18 ` Marc Kleine-Budde 2015-07-12 19:18 ` [PATCH 8/8] can: replace timestamp as unique skb attribute Marc Kleine-Budde 3 siblings, 0 replies; 6+ messages in thread From: Marc Kleine-Budde @ 2015-07-12 19:18 UTC (permalink / raw) To: netdev Cc: davem, linux-can, kernel, Roger Quadros, linux-stable, Marc Kleine-Budde From: Roger Quadros <rogerq@ti.com> Driver core sets "default" pinmux on on probe and CAN driver sets "sleep" pinmux during register. This causes a small window where the CAN pins are in "default" state with the DCAN module being disabled. Change the "default" state to be like sleep so this glitch is avoided. Add a new "active" state that is used by the driver when CAN is actually active. Signed-off-by: Roger Quadros <rogerq@ti.com> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> --- arch/arm/boot/dts/dra7-evm.dts | 5 +++-- arch/arm/boot/dts/dra72-evm.dts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index aa465904f6cc..096f68be99e2 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -686,7 +686,8 @@ &dcan1 { status = "ok"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&dcan1_pins_default>; + pinctrl-names = "default", "sleep", "active"; + pinctrl-0 = <&dcan1_pins_sleep>; pinctrl-1 = <&dcan1_pins_sleep>; + pinctrl-2 = <&dcan1_pins_default>; }; diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index 4e1b60581782..803738414086 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -587,9 +587,10 @@ &dcan1 { status = "ok"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&dcan1_pins_default>; + pinctrl-names = "default", "sleep", "active"; + pinctrl-0 = <&dcan1_pins_sleep>; pinctrl-1 = <&dcan1_pins_sleep>; + pinctrl-2 = <&dcan1_pins_default>; }; &qspi { -- 2.1.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 8/8] can: replace timestamp as unique skb attribute [not found] <1436728691-1145-1-git-send-email-mkl@pengutronix.de> ` (2 preceding siblings ...) 2015-07-12 19:18 ` [PATCH 7/8] ARM: dts: dra7x-evm: Prevent glitch on DCAN1 pinmux Marc Kleine-Budde @ 2015-07-12 19:18 ` Marc Kleine-Budde 2015-07-27 18:34 ` Oliver Hartkopp 3 siblings, 1 reply; 6+ messages in thread From: Marc Kleine-Budde @ 2015-07-12 19:18 UTC (permalink / raw) To: netdev Cc: davem, linux-can, kernel, Oliver Hartkopp, linux-stable, Marc Kleine-Budde From: Oliver Hartkopp <socketcan@hartkopp.net> Commit 514ac99c64b "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 36c01245eb8 "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> --- drivers/net/can/dev.c | 7 ++----- drivers/net/can/slcan.c | 2 +- drivers/net/can/vcan.c | 3 --- include/linux/can/skb.h | 2 ++ net/can/af_can.c | 12 +++++++----- net/can/bcm.c | 2 ++ net/can/raw.c | 7 ++++--- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index e9b1810d319f..aede704605c6 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -440,9 +440,6 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) struct can_frame *cf = (struct can_frame *)skb->data; u8 dlc = cf->can_dlc; - if (!(skb->tstamp.tv64)) - __net_timestamp(skb); - netif_rx(priv->echo_skb[idx]); priv->echo_skb[idx] = NULL; @@ -578,7 +575,6 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) if (unlikely(!skb)) return NULL; - __net_timestamp(skb); skb->protocol = htons(ETH_P_CAN); skb->pkt_type = PACKET_BROADCAST; skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -589,6 +585,7 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) can_skb_reserve(skb); can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); memset(*cf, 0, sizeof(struct can_frame)); @@ -607,7 +604,6 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev, if (unlikely(!skb)) return NULL; - __net_timestamp(skb); skb->protocol = htons(ETH_P_CANFD); skb->pkt_type = PACKET_BROADCAST; skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -618,6 +614,7 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev, can_skb_reserve(skb); can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; *cfd = (struct canfd_frame *)skb_put(skb, sizeof(struct canfd_frame)); memset(*cfd, 0, sizeof(struct canfd_frame)); diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index f64f5290d6f8..a23a7af8eb9a 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -207,7 +207,6 @@ static void slc_bump(struct slcan *sl) if (!skb) return; - __net_timestamp(skb); skb->dev = sl->dev; skb->protocol = htons(ETH_P_CAN); skb->pkt_type = PACKET_BROADCAST; @@ -215,6 +214,7 @@ static void slc_bump(struct slcan *sl) can_skb_reserve(skb); can_skb_prv(skb)->ifindex = sl->dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; memcpy(skb_put(skb, sizeof(struct can_frame)), &cf, sizeof(struct can_frame)); diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index 0ce868de855d..674f367087c5 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c @@ -78,9 +78,6 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev) skb->dev = dev; skb->ip_summed = CHECKSUM_UNNECESSARY; - if (!(skb->tstamp.tv64)) - __net_timestamp(skb); - netif_rx_ni(skb); } diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h index b6a52a4b457a..51bb6532785c 100644 --- a/include/linux/can/skb.h +++ b/include/linux/can/skb.h @@ -27,10 +27,12 @@ /** * struct can_skb_priv - private additional data inside CAN sk_buffs * @ifindex: ifindex of the first interface the CAN frame appeared on + * @skbcnt: atomic counter to have an unique id together with skb pointer * @cf: align to the following CAN frame at skb->data */ struct can_skb_priv { int ifindex; + int skbcnt; struct can_frame cf[0]; }; diff --git a/net/can/af_can.c b/net/can/af_can.c index 7933e62a7318..166d436196c1 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -89,6 +89,8 @@ struct timer_list can_stattimer; /* timer for statistics update */ struct s_stats can_stats; /* packet statistics */ struct s_pstats can_pstats; /* receive list statistics */ +static atomic_t skbcounter = ATOMIC_INIT(0); + /* * af_can socket functions */ @@ -310,12 +312,8 @@ int can_send(struct sk_buff *skb, int loop) return err; } - if (newskb) { - if (!(newskb->tstamp.tv64)) - __net_timestamp(newskb); - + if (newskb) netif_rx_ni(newskb); - } /* update statistics */ can_stats.tx_frames++; @@ -683,6 +681,10 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev) can_stats.rx_frames++; can_stats.rx_frames_delta++; + /* create non-zero unique skb identifier together with *skb */ + while (!(can_skb_prv(skb)->skbcnt)) + can_skb_prv(skb)->skbcnt = atomic_inc_return(&skbcounter); + rcu_read_lock(); /* deliver the packet to sockets listening on all devices */ diff --git a/net/can/bcm.c b/net/can/bcm.c index b523453585be..a1ba6875c2a2 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -261,6 +261,7 @@ static void bcm_can_tx(struct bcm_op *op) can_skb_reserve(skb); can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; memcpy(skb_put(skb, CFSIZ), cf, CFSIZ); @@ -1217,6 +1218,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk) } can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; skb->dev = dev; can_skb_set_owner(skb, sk); err = can_send(skb, 1); /* send with loopback */ diff --git a/net/can/raw.c b/net/can/raw.c index 31b9748cbb4e..2e67b1423cd3 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -75,7 +75,7 @@ MODULE_ALIAS("can-proto-1"); */ struct uniqframe { - ktime_t tstamp; + int skbcnt; const struct sk_buff *skb; unsigned int join_rx_count; }; @@ -133,7 +133,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data) /* eliminate multiple filter matches for the same skb */ if (this_cpu_ptr(ro->uniq)->skb == oskb && - ktime_equal(this_cpu_ptr(ro->uniq)->tstamp, oskb->tstamp)) { + this_cpu_ptr(ro->uniq)->skbcnt == can_skb_prv(oskb)->skbcnt) { if (ro->join_filters) { this_cpu_inc(ro->uniq->join_rx_count); /* drop frame until all enabled filters matched */ @@ -144,7 +144,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data) } } else { this_cpu_ptr(ro->uniq)->skb = oskb; - this_cpu_ptr(ro->uniq)->tstamp = oskb->tstamp; + this_cpu_ptr(ro->uniq)->skbcnt = can_skb_prv(oskb)->skbcnt; this_cpu_ptr(ro->uniq)->join_rx_count = 1; /* drop first frame to check all enabled filters? */ if (ro->join_filters && ro->count > 1) @@ -749,6 +749,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) can_skb_reserve(skb); can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; err = memcpy_from_msg(skb_put(skb, size), msg, size); if (err < 0) -- 2.1.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 8/8] can: replace timestamp as unique skb attribute 2015-07-12 19:18 ` [PATCH 8/8] can: replace timestamp as unique skb attribute Marc Kleine-Budde @ 2015-07-27 18:34 ` Oliver Hartkopp 2015-08-04 19:18 ` Greg KH 0 siblings, 1 reply; 6+ messages in thread From: Oliver Hartkopp @ 2015-07-27 18:34 UTC (permalink / raw) To: Greg KH; +Cc: Marc Kleine-Budde, netdev, davem, linux-can, kernel, linux-stable Hello Greg, On 12.07.2015 21:18, Marc Kleine-Budde wrote: > From: Oliver Hartkopp <socketcan@hartkopp.net> > > Commit 514ac99c64b "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 36c01245eb8 "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> Can you please queue up this missing/lost patch for the long term 4.1.x ? It fixes the mess with commits 514ac99c64b "can: fix multiple delivery of a single CAN frame for overlapping CAN filters" which originally fixed 36c01245eb8 "can: fix loss of CAN frames in raw_rcv" So finally this missing patch would bring 4.1.x into the proper state we now have in 4.2-rc4. Upstream commit of this patch is: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d3b58c47d330de8c29898fe9746f7530408f8a59 Best regards, Oliver > Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> > --- > drivers/net/can/dev.c | 7 ++----- > drivers/net/can/slcan.c | 2 +- > drivers/net/can/vcan.c | 3 --- > include/linux/can/skb.h | 2 ++ > net/can/af_can.c | 12 +++++++----- > net/can/bcm.c | 2 ++ > net/can/raw.c | 7 ++++--- > 7 files changed, 18 insertions(+), 17 deletions(-) > > diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c > index e9b1810d319f..aede704605c6 100644 > --- a/drivers/net/can/dev.c > +++ b/drivers/net/can/dev.c > @@ -440,9 +440,6 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) > struct can_frame *cf = (struct can_frame *)skb->data; > u8 dlc = cf->can_dlc; > > - if (!(skb->tstamp.tv64)) > - __net_timestamp(skb); > - > netif_rx(priv->echo_skb[idx]); > priv->echo_skb[idx] = NULL; > > @@ -578,7 +575,6 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) > if (unlikely(!skb)) > return NULL; > > - __net_timestamp(skb); > skb->protocol = htons(ETH_P_CAN); > skb->pkt_type = PACKET_BROADCAST; > skb->ip_summed = CHECKSUM_UNNECESSARY; > @@ -589,6 +585,7 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) > > can_skb_reserve(skb); > can_skb_prv(skb)->ifindex = dev->ifindex; > + can_skb_prv(skb)->skbcnt = 0; > > *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); > memset(*cf, 0, sizeof(struct can_frame)); > @@ -607,7 +604,6 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev, > if (unlikely(!skb)) > return NULL; > > - __net_timestamp(skb); > skb->protocol = htons(ETH_P_CANFD); > skb->pkt_type = PACKET_BROADCAST; > skb->ip_summed = CHECKSUM_UNNECESSARY; > @@ -618,6 +614,7 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev, > > can_skb_reserve(skb); > can_skb_prv(skb)->ifindex = dev->ifindex; > + can_skb_prv(skb)->skbcnt = 0; > > *cfd = (struct canfd_frame *)skb_put(skb, sizeof(struct canfd_frame)); > memset(*cfd, 0, sizeof(struct canfd_frame)); > diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c > index f64f5290d6f8..a23a7af8eb9a 100644 > --- a/drivers/net/can/slcan.c > +++ b/drivers/net/can/slcan.c > @@ -207,7 +207,6 @@ static void slc_bump(struct slcan *sl) > if (!skb) > return; > > - __net_timestamp(skb); > skb->dev = sl->dev; > skb->protocol = htons(ETH_P_CAN); > skb->pkt_type = PACKET_BROADCAST; > @@ -215,6 +214,7 @@ static void slc_bump(struct slcan *sl) > > can_skb_reserve(skb); > can_skb_prv(skb)->ifindex = sl->dev->ifindex; > + can_skb_prv(skb)->skbcnt = 0; > > memcpy(skb_put(skb, sizeof(struct can_frame)), > &cf, sizeof(struct can_frame)); > diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c > index 0ce868de855d..674f367087c5 100644 > --- a/drivers/net/can/vcan.c > +++ b/drivers/net/can/vcan.c > @@ -78,9 +78,6 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev) > skb->dev = dev; > skb->ip_summed = CHECKSUM_UNNECESSARY; > > - if (!(skb->tstamp.tv64)) > - __net_timestamp(skb); > - > netif_rx_ni(skb); > } > > diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h > index b6a52a4b457a..51bb6532785c 100644 > --- a/include/linux/can/skb.h > +++ b/include/linux/can/skb.h > @@ -27,10 +27,12 @@ > /** > * struct can_skb_priv - private additional data inside CAN sk_buffs > * @ifindex: ifindex of the first interface the CAN frame appeared on > + * @skbcnt: atomic counter to have an unique id together with skb pointer > * @cf: align to the following CAN frame at skb->data > */ > struct can_skb_priv { > int ifindex; > + int skbcnt; > struct can_frame cf[0]; > }; > > diff --git a/net/can/af_can.c b/net/can/af_can.c > index 7933e62a7318..166d436196c1 100644 > --- a/net/can/af_can.c > +++ b/net/can/af_can.c > @@ -89,6 +89,8 @@ struct timer_list can_stattimer; /* timer for statistics update */ > struct s_stats can_stats; /* packet statistics */ > struct s_pstats can_pstats; /* receive list statistics */ > > +static atomic_t skbcounter = ATOMIC_INIT(0); > + > /* > * af_can socket functions > */ > @@ -310,12 +312,8 @@ int can_send(struct sk_buff *skb, int loop) > return err; > } > > - if (newskb) { > - if (!(newskb->tstamp.tv64)) > - __net_timestamp(newskb); > - > + if (newskb) > netif_rx_ni(newskb); > - } > > /* update statistics */ > can_stats.tx_frames++; > @@ -683,6 +681,10 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev) > can_stats.rx_frames++; > can_stats.rx_frames_delta++; > > + /* create non-zero unique skb identifier together with *skb */ > + while (!(can_skb_prv(skb)->skbcnt)) > + can_skb_prv(skb)->skbcnt = atomic_inc_return(&skbcounter); > + > rcu_read_lock(); > > /* deliver the packet to sockets listening on all devices */ > diff --git a/net/can/bcm.c b/net/can/bcm.c > index b523453585be..a1ba6875c2a2 100644 > --- a/net/can/bcm.c > +++ b/net/can/bcm.c > @@ -261,6 +261,7 @@ static void bcm_can_tx(struct bcm_op *op) > > can_skb_reserve(skb); > can_skb_prv(skb)->ifindex = dev->ifindex; > + can_skb_prv(skb)->skbcnt = 0; > > memcpy(skb_put(skb, CFSIZ), cf, CFSIZ); > > @@ -1217,6 +1218,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk) > } > > can_skb_prv(skb)->ifindex = dev->ifindex; > + can_skb_prv(skb)->skbcnt = 0; > skb->dev = dev; > can_skb_set_owner(skb, sk); > err = can_send(skb, 1); /* send with loopback */ > diff --git a/net/can/raw.c b/net/can/raw.c > index 31b9748cbb4e..2e67b1423cd3 100644 > --- a/net/can/raw.c > +++ b/net/can/raw.c > @@ -75,7 +75,7 @@ MODULE_ALIAS("can-proto-1"); > */ > > struct uniqframe { > - ktime_t tstamp; > + int skbcnt; > const struct sk_buff *skb; > unsigned int join_rx_count; > }; > @@ -133,7 +133,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data) > > /* eliminate multiple filter matches for the same skb */ > if (this_cpu_ptr(ro->uniq)->skb == oskb && > - ktime_equal(this_cpu_ptr(ro->uniq)->tstamp, oskb->tstamp)) { > + this_cpu_ptr(ro->uniq)->skbcnt == can_skb_prv(oskb)->skbcnt) { > if (ro->join_filters) { > this_cpu_inc(ro->uniq->join_rx_count); > /* drop frame until all enabled filters matched */ > @@ -144,7 +144,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data) > } > } else { > this_cpu_ptr(ro->uniq)->skb = oskb; > - this_cpu_ptr(ro->uniq)->tstamp = oskb->tstamp; > + this_cpu_ptr(ro->uniq)->skbcnt = can_skb_prv(oskb)->skbcnt; > this_cpu_ptr(ro->uniq)->join_rx_count = 1; > /* drop first frame to check all enabled filters? */ > if (ro->join_filters && ro->count > 1) > @@ -749,6 +749,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) > > can_skb_reserve(skb); > can_skb_prv(skb)->ifindex = dev->ifindex; > + can_skb_prv(skb)->skbcnt = 0; > > err = memcpy_from_msg(skb_put(skb, size), msg, size); > if (err < 0) > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 8/8] can: replace timestamp as unique skb attribute 2015-07-27 18:34 ` Oliver Hartkopp @ 2015-08-04 19:18 ` Greg KH 0 siblings, 0 replies; 6+ messages in thread From: Greg KH @ 2015-08-04 19:18 UTC (permalink / raw) To: Oliver Hartkopp Cc: Marc Kleine-Budde, netdev, davem, linux-can, kernel, linux-stable On Mon, Jul 27, 2015 at 08:34:32PM +0200, Oliver Hartkopp wrote: > Hello Greg, > > On 12.07.2015 21:18, Marc Kleine-Budde wrote: > >From: Oliver Hartkopp <socketcan@hartkopp.net> > > > >Commit 514ac99c64b "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 36c01245eb8 "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> > > Can you please queue up this missing/lost patch for the long term 4.1.x ? > > It fixes the mess with commits > > 514ac99c64b "can: fix multiple delivery of a single CAN frame for > overlapping CAN filters" > > which originally fixed > > 36c01245eb8 "can: fix loss of CAN frames in raw_rcv" > > So finally this missing patch would bring 4.1.x into the proper state we now > have in 4.2-rc4. > > Upstream commit of this patch is: > > http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d3b58c47d330de8c29898fe9746f7530408f8a59 It's in my queue, I still have way over 200 commits to get through for 4.1.x, your patches are in good company. greg k-h ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-08-04 19:18 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1436728691-1145-1-git-send-email-mkl@pengutronix.de>
2015-07-12 19:18 ` [PATCH 1/8] can: rcar_can: fix IRQ check Marc Kleine-Budde
2015-07-12 19:18 ` [PATCH 6/8] can: c_can: Fix default pinmux glitch at init Marc Kleine-Budde
2015-07-12 19:18 ` [PATCH 7/8] ARM: dts: dra7x-evm: Prevent glitch on DCAN1 pinmux Marc Kleine-Budde
2015-07-12 19:18 ` [PATCH 8/8] can: replace timestamp as unique skb attribute Marc Kleine-Budde
2015-07-27 18:34 ` Oliver Hartkopp
2015-08-04 19:18 ` Greg KH
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).