can sja1000: Only create requested error messages
Subsystems (2)
Oliver Hartkopp
maintainerRFC PATCH 1/1 can sja1000: Only create requested error messages
This is a proof of concept for the SJA1000 only.
Idea: Only create error message skbuffs when there is a request from a CAN application which sets a filter for error messages.
Drawback: can.ko has to be available in the system to access the CAN filter structures. This is usually the case. Alternatively the filter structures could be made in linux/include/can/core.h instead of only providing a new function can_dev_has_error_filter() there.
Don't know if this is 'nice design' then ?!?
Regards,
Oliver
---
drivers/net/can/dev.c +7 -0
@@ -25,6 +25,7 @@#include <linux/can.h> #include <linux/can/dev.h> #include <linux/can/skb.h> +#include <linux/can/core.h> /* only for can_dev_error_has_filter() */ #include <linux/can/netlink.h> #include <linux/can/led.h> #include <net/rtnetlink.h>
@@ -537,6 +538,12 @@ struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) }EXPORT_SYMBOL_GPL (alloc_can_err_skb); +bool can_need_error_skb (struct net_device *dev) +{ +return can_dev_has_error_filter (dev); +} +EXPORT_SYMBOL_GPL (can_need_error_skb); +/* * Allocate and setup space for the CAN network device */
drivers/net/can/sja1000/sja1000.c +74 -45
162 lines not on this page · raw message
include/linux/can/core.h +1 -0
@@ -57,5 +57,6 @@ extern void can_rx_unregister(struct net_device *dev, canid_t can_id,extern int can_send (struct sk_buff *skb,int loop);extern int can_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg); +extern bool can_dev_has_error_filter (struct net_device *dev);#endif /* CAN_CORE_H */
include/linux/can/dev.h +1 -0
@@ -126,5 +126,6 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx);struct sk_buff *alloc_can_skb (struct net_device *dev,struct can_frame **cf);struct sk_buff *alloc_can_err_skb (struct net_device *dev,struct can_frame **cf); +bool can_need_error_skb (struct net_device *dev);#endif /* CAN_DEV_H */
net/can/af_can.c +14 -0
@@ -328,6 +328,20 @@ EXPORT_SYMBOL(can_send);* af_can rx path */ +bool can_dev_has_error_filter (struct net_device *dev) +{ +if (dev) { +struct dev_rcv_lists *rcvlist; + + rcvlist = (struct dev_rcv_lists *)dev->ml_priv; +if (&rcvlist->rx[RX_ERR ] !=NULL || + &can_rx_alldev_list.rx[RX_ERR ] !=NULL ) +return true; + } +return false; +} +EXPORT_SYMBOL (can_dev_has_error_filter); +static struct dev_rcv_lists *find_dev_rcv_lists (struct net_device *dev) {if (!dev)