Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: introduce CAN midlayer private and allocate it automatically

This patch introduces the CAN midlayer private structure ("struct
can_ml_priv") which should be used to hold protocol specific per device
data structures. For now it's only member is "struct can_dev_rcv_lists".

The CAN midlayer private is allocated via alloc_netdev()'s private and
assigned to "struct net_device::ml_priv" during device creation. This is
done transparently for CAN drivers using alloc_candev(). The slcan, vcan
and vxcan drivers which are not using alloc_candev() have been adopted
manually. The memory layout of the netdev_priv allocated via
alloc_candev() will looke like this:

+-------------------------+
| driver's priv |
+-------------------------+
| struct can_ml_priv |
+-------------------------+
| array of struct sk_buff |
+-------------------------+

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

+96 -23
+18 -4
drivers/net/can/dev.c
··· 12 12 #include <linux/if_arp.h> 13 13 #include <linux/workqueue.h> 14 14 #include <linux/can.h> 15 + #include <linux/can/can-ml.h> 15 16 #include <linux/can/dev.h> 16 17 #include <linux/can/skb.h> 17 18 #include <linux/can/netlink.h> ··· 719 718 struct can_priv *priv; 720 719 int size; 721 720 721 + /* We put the driver's priv, the CAN mid layer priv and the 722 + * echo skb into the netdevice's priv. The memory layout for 723 + * the netdev_priv is like this: 724 + * 725 + * +-------------------------+ 726 + * | driver's priv | 727 + * +-------------------------+ 728 + * | struct can_ml_priv | 729 + * +-------------------------+ 730 + * | array of struct sk_buff | 731 + * +-------------------------+ 732 + */ 733 + 734 + size = ALIGN(sizeof_priv, NETDEV_ALIGN) + sizeof(struct can_ml_priv); 735 + 722 736 if (echo_skb_max) 723 - size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) + 737 + size = ALIGN(size, sizeof(struct sk_buff *)) + 724 738 echo_skb_max * sizeof(struct sk_buff *); 725 - else 726 - size = sizeof_priv; 727 739 728 740 dev = alloc_netdev_mqs(size, "can%d", NET_NAME_UNKNOWN, can_setup, 729 741 txqs, rxqs); ··· 749 735 if (echo_skb_max) { 750 736 priv->echo_skb_max = echo_skb_max; 751 737 priv->echo_skb = (void *)priv + 752 - ALIGN(sizeof_priv, sizeof(struct sk_buff *)); 738 + (size - echo_skb_max * sizeof(struct sk_buff *)); 753 739 } 754 740 755 741 priv->state = CAN_STATE_STOPPED;
+4 -1
drivers/net/can/slcan.c
··· 55 55 #include <linux/workqueue.h> 56 56 #include <linux/can.h> 57 57 #include <linux/can/skb.h> 58 + #include <linux/can/can-ml.h> 58 59 59 60 MODULE_ALIAS_LDISC(N_SLCAN); 60 61 MODULE_DESCRIPTION("serial line CAN interface"); ··· 515 514 char name[IFNAMSIZ]; 516 515 struct net_device *dev = NULL; 517 516 struct slcan *sl; 517 + int size; 518 518 519 519 for (i = 0; i < maxdev; i++) { 520 520 dev = slcan_devs[i]; ··· 529 527 return NULL; 530 528 531 529 sprintf(name, "slcan%d", i); 532 - dev = alloc_netdev(sizeof(*sl), name, NET_NAME_UNKNOWN, slc_setup); 530 + size = ALIGN(sizeof(*sl), NETDEV_ALIGN) + sizeof(struct can_ml_priv); 531 + dev = alloc_netdev(size, name, NET_NAME_UNKNOWN, slc_setup); 533 532 if (!dev) 534 533 return NULL; 535 534
+4 -2
drivers/net/can/vcan.c
··· 46 46 #include <linux/if_arp.h> 47 47 #include <linux/if_ether.h> 48 48 #include <linux/can.h> 49 + #include <linux/can/can-ml.h> 49 50 #include <linux/can/dev.h> 50 51 #include <linux/can/skb.h> 51 52 #include <linux/slab.h> ··· 163 162 } 164 163 165 164 static struct rtnl_link_ops vcan_link_ops __read_mostly = { 166 - .kind = DRV_NAME, 167 - .setup = vcan_setup, 165 + .kind = DRV_NAME, 166 + .priv_size = sizeof(struct can_ml_priv), 167 + .setup = vcan_setup, 168 168 }; 169 169 170 170 static __init int vcan_init_module(void)
+2 -1
drivers/net/can/vxcan.c
··· 18 18 #include <linux/can/dev.h> 19 19 #include <linux/can/skb.h> 20 20 #include <linux/can/vxcan.h> 21 + #include <linux/can/can-ml.h> 21 22 #include <linux/slab.h> 22 23 #include <net/rtnetlink.h> 23 24 ··· 282 281 283 282 static struct rtnl_link_ops vxcan_link_ops = { 284 283 .kind = DRV_NAME, 285 - .priv_size = sizeof(struct vxcan_priv), 284 + .priv_size = ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN) + sizeof(struct can_ml_priv), 286 285 .setup = vxcan_setup, 287 286 .newlink = vxcan_newlink, 288 287 .dellink = vxcan_dellink,
+66
include/linux/can/can-ml.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ 2 + /* Copyright (c) 2002-2007 Volkswagen Group Electronic Research 3 + * Copyright (c) 2017 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de> 4 + * 5 + * All rights reserved. 6 + * 7 + * Redistribution and use in source and binary forms, with or without 8 + * modification, are permitted provided that the following conditions 9 + * are met: 10 + * 1. Redistributions of source code must retain the above copyright 11 + * notice, this list of conditions and the following disclaimer. 12 + * 2. Redistributions in binary form must reproduce the above copyright 13 + * notice, this list of conditions and the following disclaimer in the 14 + * documentation and/or other materials provided with the distribution. 15 + * 3. Neither the name of Volkswagen nor the names of its contributors 16 + * may be used to endorse or promote products derived from this software 17 + * without specific prior written permission. 18 + * 19 + * Alternatively, provided that this notice is retained in full, this 20 + * software may be distributed under the terms of the GNU General 21 + * Public License ("GPL") version 2, in which case the provisions of the 22 + * GPL apply INSTEAD OF those given above. 23 + * 24 + * The provided data structures and external interfaces from this code 25 + * are not restricted to be used by modules with a GPL compatible license. 26 + * 27 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 38 + * DAMAGE. 39 + * 40 + */ 41 + 42 + #ifndef CAN_ML_H 43 + #define CAN_ML_H 44 + 45 + #include <linux/can.h> 46 + #include <linux/list.h> 47 + 48 + #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS) 49 + #define CAN_EFF_RCV_HASH_BITS 10 50 + #define CAN_EFF_RCV_ARRAY_SZ (1 << CAN_EFF_RCV_HASH_BITS) 51 + 52 + enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_MAX }; 53 + 54 + struct can_dev_rcv_lists { 55 + struct hlist_head rx[RX_MAX]; 56 + struct hlist_head rx_sff[CAN_SFF_RCV_ARRAY_SZ]; 57 + struct hlist_head rx_eff[CAN_EFF_RCV_ARRAY_SZ]; 58 + int remove_on_zero_entries; 59 + int entries; 60 + }; 61 + 62 + struct can_ml_priv { 63 + struct can_dev_rcv_lists dev_rcv_lists; 64 + }; 65 + 66 + #endif /* CAN_ML_H */
+1
net/can/af_can.c
··· 58 58 #include <linux/can.h> 59 59 #include <linux/can/core.h> 60 60 #include <linux/can/skb.h> 61 + #include <linux/can/can-ml.h> 61 62 #include <linux/ratelimit.h> 62 63 #include <net/net_namespace.h> 63 64 #include <net/sock.h>
-15
net/can/af_can.h
··· 60 60 struct rcu_head rcu; 61 61 }; 62 62 63 - #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS) 64 - #define CAN_EFF_RCV_HASH_BITS 10 65 - #define CAN_EFF_RCV_ARRAY_SZ (1 << CAN_EFF_RCV_HASH_BITS) 66 - 67 - enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_MAX }; 68 - 69 - /* per device receive filters linked at dev->ml_priv */ 70 - struct can_dev_rcv_lists { 71 - struct hlist_head rx[RX_MAX]; 72 - struct hlist_head rx_sff[CAN_SFF_RCV_ARRAY_SZ]; 73 - struct hlist_head rx_eff[CAN_EFF_RCV_ARRAY_SZ]; 74 - int remove_on_zero_entries; 75 - int entries; 76 - }; 77 - 78 63 /* statistic structures */ 79 64 80 65 /* can be reset e.g. by can_init_stats() */
+1
net/can/proc.c
··· 45 45 #include <linux/list.h> 46 46 #include <linux/rcupdate.h> 47 47 #include <linux/if_arp.h> 48 + #include <linux/can/can-ml.h> 48 49 #include <linux/can/core.h> 49 50 50 51 #include "af_can.h"