History

can: make use of preallocated can_ml_priv for per device struct can_dev_rcv_lists

This patch removes the old method of allocating the per device protocol specific memory via a netdevice_notifier. This had the drawback, that the allocation can fail, leading to a lot of null pointer checks in the code. This also makes the live cycle management of this memory quite complicated. This patch switches from the allocating the struct can_dev_rcv_lists in a NETDEV_REGISTER call to using the dev->ml_priv, which is allocated by the driver since the previous patch.

Marc Kleine-Budde committed 8 years ago

Commit 8df9ffb1 parent ffd956e6 files · +12 −39Browse files

Unified · Split

6 files
  1. drivers/net/can/dev.c +2 −0
  2. drivers/net/can/slcan.c +1 −0
  3. drivers/net/can/vcan.c +1 −0
  4. drivers/net/can/vxcan.c +1 −0
  5. include/linux/can/can-ml.h +0 −1
  6. net/can/af_can.c +7 −38
drivers/net/can/dev.c+2−0
@@ -746,6 +746,8 @@ struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max, · 745 unmodified lines
746746 priv = netdev_priv(dev);
747747 priv->dev = dev;
748748
749+ dev->ml_priv = (void *)priv + ALIGN(sizeof_priv, NETDEV_ALIGN);
750+
749751 if (echo_skb_max) {
750752 priv->echo_skb_max = echo_skb_max;
751753 priv->echo_skb = (void *)priv +
drivers/net/can/slcan.c+1−0
@@ -536,6 +536,7 @@ static struct slcan *slc_alloc(void) · 535 unmodified lines
536536
537537 dev->base_addr = i;
538538 sl = netdev_priv(dev);
539+ dev->ml_priv = (void *)sl + ALIGN(sizeof(*sl), NETDEV_ALIGN);
539540
540541 /* Initialize channel control data */
541542 sl->magic = SLCAN_MAGIC;
drivers/net/can/vcan.c+1−0
@@ -153,6 +153,7 @@ static void vcan_setup(struct net_device *dev) · 152 unmodified lines
153153 dev->addr_len = 0;
154154 dev->tx_queue_len = 0;
155155 dev->flags = IFF_NOARP;
156+ dev->ml_priv = netdev_priv(dev);
156157
157158 /* set flags according to driver capabilities */
158159 if (echo)
drivers/net/can/vxcan.c+1−0
@@ -147,6 +147,7 @@ static void vxcan_setup(struct net_device *dev) · 146 unmodified lines
147147 dev->flags = (IFF_NOARP|IFF_ECHO);
148148 dev->netdev_ops = &vxcan_netdev_ops;
149149 dev->needs_free_netdev = true;
150+ dev->ml_priv = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
150151 }
151152
152153 /* forward declaration for rtnl_create_link() */
include/linux/can/can-ml.h+0−1
@@ -55,7 +55,6 @@ struct can_dev_rcv_lists { · 54 unmodified lines
5555 struct hlist_head rx[RX_MAX];
5656 struct hlist_head rx_sff[CAN_SFF_RCV_ARRAY_SZ];
5757 struct hlist_head rx_eff[CAN_EFF_RCV_ARRAY_SZ];
58− int remove_on_zero_entries;
5958 int entries;
6059 };
6160
net/can/af_can.c+7−38
@@ -302,10 +302,12 @@ EXPORT_SYMBOL(can_send); · 301 unmodified lines
302302 static struct can_dev_rcv_lists *can_dev_rcv_lists_find(struct net *net,
303303 struct net_device *dev)
304304 {
305− if (!dev)
305+ if (dev) {
306+ struct can_ml_priv *ml_priv = dev->ml_priv;
307+ return &ml_priv->dev_rcv_lists;
308+ } else {
306309 return net->can.rx_alldev_list;
307− else
308− return (struct can_dev_rcv_lists *)dev->ml_priv;
310+ }
309311 }
310312
311313 /**
@@ -561,12 +563,6 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id, · 249 unmodified lines
561563 if (rcv_lists_stats->rcv_entries > 0)
562564 rcv_lists_stats->rcv_entries--;
563565
564− /* remove device structure requested by NETDEV_UNREGISTER */
565− if (dev_rcv_lists->remove_on_zero_entries && !dev_rcv_lists->entries) {
566− kfree(dev_rcv_lists);
567− dev->ml_priv = NULL;
568− }
569−
570566 out:
571567 spin_unlock(&net->can.rcvlists_lock);
572568
@@ -788,41 +784,14 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, · 215 unmodified lines
788784 void *ptr)
789785 {
790786 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
791− struct can_dev_rcv_lists *dev_rcv_lists;
792787
793788 if (dev->type != ARPHRD_CAN)
794789 return NOTIFY_DONE;
795790
796791 switch (msg) {
797792 case NETDEV_REGISTER:
798−
799− /* create new dev_rcv_lists for this device */
800− dev_rcv_lists = kzalloc(sizeof(*dev_rcv_lists), GFP_KERNEL);
801− if (!dev_rcv_lists)
802− return NOTIFY_DONE;
803− BUG_ON(dev->ml_priv);
804− dev->ml_priv = dev_rcv_lists;
805−
806− break;
807−
808− case NETDEV_UNREGISTER:
809− spin_lock(&dev_net(dev)->can.rcvlists_lock);
810−
811− dev_rcv_lists = dev->ml_priv;
812− if (dev_rcv_lists) {
813− if (dev_rcv_lists->entries)
814− dev_rcv_lists->remove_on_zero_entries = 1;
815− else {
816− kfree(dev_rcv_lists);
817− dev->ml_priv = NULL;
818− }
819− } else {
820− pr_err("can: notifier: receive list not found for dev %s\n",
821− dev->name);
822− }
823−
824− spin_unlock(&dev_net(dev)->can.rcvlists_lock);
825−
793+ WARN(!dev->ml_priv,
794+ "No CAN mid layer private allocated, please fix your driver and use alloc_candev()!\n");
826795 break;
827796 }
828797

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t