網絡設備之分配net_device結構
阿新 • • 發佈:2017-09-15
unsigned ethernet 默認 eem def 填充 init callback char
註冊網絡設備時,會調用pci_driver->probe函數,以e100為例,最終會調用alloc_netdev_mqs來分配內存,並且在分配內存後調用setup函數(以太網為ether_setup)初始化二層地址等信息,這裏主要分析alloc_netdev_mqs函數,以及ether_setup函數:
e100_probe----->alloc_etherdev----->alloc_netdev_mqs
|
|---->ether_setup
1 /** 2 * alloc_netdev_mqs - allocate network device 3 * @sizeof_priv: size of private data to allocate space for 4 * @name: device name format string 5 * @name_assign_type: origin of device name 6 * @setup: callback to initialize device 7 * @txqs: the number of TX subqueues to allocate8 * @rxqs: the number of RX subqueues to allocate 9 * 10 * Allocates a struct net_device with private data area for driver use 11 * and performs basic initialization. Also allocates subqueue structs 12 * for each queue on the device. 13 */ 14 struct net_device *alloc_netdev_mqs(intsizeof_priv, const char *name, 15 unsigned char name_assign_type, 16 void (*setup)(struct net_device *), 17 unsigned int txqs, unsigned int rxqs) 18 { 19 struct net_device *dev; 20 size_t alloc_size; 21 struct net_device *p; 22 23 BUG_ON(strlen(name) >= sizeof(dev->name)); 24 25 /* 檢查發送隊列數 */ 26 if (txqs < 1) { 27 pr_err("alloc_netdev: Unable to allocate device with zero queues\n"); 28 return NULL; 29 } 30 31 /* 檢查接收隊列數 */ 32 #ifdef CONFIG_SYSFS 33 if (rxqs < 1) { 34 pr_err("alloc_netdev: Unable to allocate device with zero RX queues\n"); 35 return NULL; 36 } 37 #endif 38 39 /* 計算net_device結構大小 */ 40 alloc_size = sizeof(struct net_device); 41 /* 加上私有數據大小 */ 42 if (sizeof_priv) { 43 /* ensure 32-byte alignment of private area */ 44 alloc_size = ALIGN(alloc_size, NETDEV_ALIGN); 45 alloc_size += sizeof_priv; 46 } 47 /* ensure 32-byte alignment of whole construct */ 48 /* 整個空間做對齊後的大小 */ 49 alloc_size += NETDEV_ALIGN - 1; 50 51 /* 分配內存 */ 52 p = kvzalloc(alloc_size, GFP_KERNEL | __GFP_REPEAT); 53 if (!p) 54 return NULL; 55 56 /* 內存對齊 */ 57 dev = PTR_ALIGN(p, NETDEV_ALIGN); 58 59 /* 計算對齊的填充 */ 60 dev->padded = (char *)dev - (char *)p; 61 62 /* 分配設備引用 */ 63 dev->pcpu_refcnt = alloc_percpu(int); 64 if (!dev->pcpu_refcnt) 65 goto free_dev; 66 67 /* 地址列表初始化 */ 68 if (dev_addr_init(dev)) 69 goto free_pcpu; 70 71 /* 組播列表初始化 */ 72 dev_mc_init(dev); 73 74 /* 單播列表初始化 */ 75 dev_uc_init(dev); 76 77 /* 設置net */ 78 dev_net_set(dev, &init_net); 79 80 /* GSO設置 */ 81 dev->gso_max_size = GSO_MAX_SIZE; 82 dev->gso_max_segs = GSO_MAX_SEGS; 83 84 /* 初始化各種鏈表 */ 85 INIT_LIST_HEAD(&dev->napi_list); 86 INIT_LIST_HEAD(&dev->unreg_list); 87 INIT_LIST_HEAD(&dev->close_list); 88 INIT_LIST_HEAD(&dev->link_watch_list); 89 INIT_LIST_HEAD(&dev->adj_list.upper); 90 INIT_LIST_HEAD(&dev->adj_list.lower); 91 INIT_LIST_HEAD(&dev->ptype_all); 92 INIT_LIST_HEAD(&dev->ptype_specific); 93 #ifdef CONFIG_NET_SCHED 94 hash_init(dev->qdisc_hash); 95 #endif 96 dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM; 97 98 /* 初始化設備硬件地址,mtu等參數 */ 99 setup(dev); 100 101 /* 隊列長度為0,則采用默認值 */ 102 if (!dev->tx_queue_len) { 103 dev->priv_flags |= IFF_NO_QUEUE; 104 dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; 105 } 106 107 /* 設置發送隊列數 */ 108 dev->num_tx_queues = txqs; 109 dev->real_num_tx_queues = txqs; 110 111 /* 分配初始化發送隊列 */ 112 if (netif_alloc_netdev_queues(dev)) 113 goto free_all; 114 115 #ifdef CONFIG_SYSFS 116 /* 設置接收隊列數 */ 117 dev->num_rx_queues = rxqs; 118 dev->real_num_rx_queues = rxqs; 119 120 /* 分配初始化接收隊列 */ 121 if (netif_alloc_rx_queues(dev)) 122 goto free_all; 123 #endif 124 125 /* 拷貝名字 */ 126 strcpy(dev->name, name); 127 128 /* 賦值名字賦值類型 */ 129 dev->name_assign_type = name_assign_type; 130 131 /* 設置設備組 */ 132 dev->group = INIT_NETDEV_GROUP; 133 134 /* 設置默認ethtool操作 */ 135 if (!dev->ethtool_ops) 136 dev->ethtool_ops = &default_ethtool_ops; 137 138 /* 初始化netfilter入口 */ 139 nf_hook_ingress_init(dev); 140 141 return dev; 142 143 free_all: 144 free_netdev(dev); 145 return NULL; 146 147 free_pcpu: 148 free_percpu(dev->pcpu_refcnt); 149 free_dev: 150 netdev_freemem(dev); 151 return NULL; 152 }
1 /** 2 * ether_setup - setup Ethernet network device 3 * @dev: network device 4 * 5 * Fill in the fields of the device structure with Ethernet-generic values. 6 */ 7 void ether_setup(struct net_device *dev) 8 { 9 dev->header_ops = ð_header_ops; 10 dev->type = ARPHRD_ETHER; 11 dev->hard_header_len = ETH_HLEN; 12 dev->min_header_len = ETH_HLEN; 13 dev->mtu = ETH_DATA_LEN; 14 dev->min_mtu = ETH_MIN_MTU; 15 dev->max_mtu = ETH_DATA_LEN; 16 dev->addr_len = ETH_ALEN; 17 dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; 18 dev->flags = IFF_BROADCAST|IFF_MULTICAST; 19 dev->priv_flags |= IFF_TX_SKB_SHARING; 20 21 eth_broadcast_addr(dev->broadcast); 22 23 }
網絡設備之分配net_device結構