forked from mirrors/linux
		
	xdp: generic XDP handling of xdp_rxq_info
Hook points for xdp_rxq_info: * reg : netif_alloc_rx_queues * unreg: netif_free_rx_queues The net_device have some members (num_rx_queues + real_num_rx_queues) and data-area (dev->_rx with struct netdev_rx_queue's) that were primarily used for exporting information about RPS (CONFIG_RPS) queues to sysfs (CONFIG_SYSFS). For generic XDP extend struct netdev_rx_queue with the xdp_rxq_info, and remove some of the CONFIG_SYSFS ifdefs. Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
		
							parent
							
								
									754b8a21a9
								
							
						
					
					
						commit
						e817f85652
					
				
					 2 changed files with 61 additions and 10 deletions
				
			
		|  | @ -44,6 +44,7 @@ | |||
| #include <net/dcbnl.h> | ||||
| #endif | ||||
| #include <net/netprio_cgroup.h> | ||||
| #include <net/xdp.h> | ||||
| 
 | ||||
| #include <linux/netdev_features.h> | ||||
| #include <linux/neighbour.h> | ||||
|  | @ -686,6 +687,7 @@ struct netdev_rx_queue { | |||
| #endif | ||||
| 	struct kobject			kobj; | ||||
| 	struct net_device		*dev; | ||||
| 	struct xdp_rxq_info		xdp_rxq; | ||||
| } ____cacheline_aligned_in_smp; | ||||
| 
 | ||||
| /*
 | ||||
|  |  | |||
|  | @ -3906,9 +3906,33 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu, | |||
| 	return NET_RX_DROP; | ||||
| } | ||||
| 
 | ||||
| static struct netdev_rx_queue *netif_get_rxqueue(struct sk_buff *skb) | ||||
| { | ||||
| 	struct net_device *dev = skb->dev; | ||||
| 	struct netdev_rx_queue *rxqueue; | ||||
| 
 | ||||
| 	rxqueue = dev->_rx; | ||||
| 
 | ||||
| 	if (skb_rx_queue_recorded(skb)) { | ||||
| 		u16 index = skb_get_rx_queue(skb); | ||||
| 
 | ||||
| 		if (unlikely(index >= dev->real_num_rx_queues)) { | ||||
| 			WARN_ONCE(dev->real_num_rx_queues > 1, | ||||
| 				  "%s received packet on queue %u, but number " | ||||
| 				  "of RX queues is %u\n", | ||||
| 				  dev->name, index, dev->real_num_rx_queues); | ||||
| 
 | ||||
| 			return rxqueue; /* Return first rxqueue */ | ||||
| 		} | ||||
| 		rxqueue += index; | ||||
| 	} | ||||
| 	return rxqueue; | ||||
| } | ||||
| 
 | ||||
| static u32 netif_receive_generic_xdp(struct sk_buff *skb, | ||||
| 				     struct bpf_prog *xdp_prog) | ||||
| { | ||||
| 	struct netdev_rx_queue *rxqueue; | ||||
| 	u32 metalen, act = XDP_DROP; | ||||
| 	struct xdp_buff xdp; | ||||
| 	void *orig_data; | ||||
|  | @ -3952,6 +3976,9 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, | |||
| 	xdp.data_hard_start = skb->data - skb_headroom(skb); | ||||
| 	orig_data = xdp.data; | ||||
| 
 | ||||
| 	rxqueue = netif_get_rxqueue(skb); | ||||
| 	xdp.rxq = &rxqueue->xdp_rxq; | ||||
| 
 | ||||
| 	act = bpf_prog_run_xdp(xdp_prog, &xdp); | ||||
| 
 | ||||
| 	off = xdp.data - orig_data; | ||||
|  | @ -7589,12 +7616,12 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev, | |||
| } | ||||
| EXPORT_SYMBOL(netif_stacked_transfer_operstate); | ||||
| 
 | ||||
| #ifdef CONFIG_SYSFS | ||||
| static int netif_alloc_rx_queues(struct net_device *dev) | ||||
| { | ||||
| 	unsigned int i, count = dev->num_rx_queues; | ||||
| 	struct netdev_rx_queue *rx; | ||||
| 	size_t sz = count * sizeof(*rx); | ||||
| 	int err = 0; | ||||
| 
 | ||||
| 	BUG_ON(count < 1); | ||||
| 
 | ||||
|  | @ -7604,11 +7631,39 @@ static int netif_alloc_rx_queues(struct net_device *dev) | |||
| 
 | ||||
| 	dev->_rx = rx; | ||||
| 
 | ||||
| 	for (i = 0; i < count; i++) | ||||
| 	for (i = 0; i < count; i++) { | ||||
| 		rx[i].dev = dev; | ||||
| 
 | ||||
| 		/* XDP RX-queue setup */ | ||||
| 		err = xdp_rxq_info_reg(&rx[i].xdp_rxq, dev, i); | ||||
| 		if (err < 0) | ||||
| 			goto err_rxq_info; | ||||
| 	} | ||||
| 	return 0; | ||||
| 
 | ||||
| err_rxq_info: | ||||
| 	/* Rollback successful reg's and free other resources */ | ||||
| 	while (i--) | ||||
| 		xdp_rxq_info_unreg(&rx[i].xdp_rxq); | ||||
| 	kfree(dev->_rx); | ||||
| 	dev->_rx = NULL; | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static void netif_free_rx_queues(struct net_device *dev) | ||||
| { | ||||
| 	unsigned int i, count = dev->num_rx_queues; | ||||
| 	struct netdev_rx_queue *rx; | ||||
| 
 | ||||
| 	/* netif_alloc_rx_queues alloc failed, resources have been unreg'ed */ | ||||
| 	if (!dev->_rx) | ||||
| 		return; | ||||
| 
 | ||||
| 	rx = dev->_rx; | ||||
| 
 | ||||
| 	for (i = 0; i < count; i++) | ||||
| 		xdp_rxq_info_unreg(&rx[i].xdp_rxq); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static void netdev_init_one_queue(struct net_device *dev, | ||||
| 				  struct netdev_queue *queue, void *_unused) | ||||
|  | @ -8169,12 +8224,10 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, | |||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| #ifdef CONFIG_SYSFS | ||||
| 	if (rxqs < 1) { | ||||
| 		pr_err("alloc_netdev: Unable to allocate device with zero RX queues\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	alloc_size = sizeof(struct net_device); | ||||
| 	if (sizeof_priv) { | ||||
|  | @ -8231,12 +8284,10 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, | |||
| 	if (netif_alloc_netdev_queues(dev)) | ||||
| 		goto free_all; | ||||
| 
 | ||||
| #ifdef CONFIG_SYSFS | ||||
| 	dev->num_rx_queues = rxqs; | ||||
| 	dev->real_num_rx_queues = rxqs; | ||||
| 	if (netif_alloc_rx_queues(dev)) | ||||
| 		goto free_all; | ||||
| #endif | ||||
| 
 | ||||
| 	strcpy(dev->name, name); | ||||
| 	dev->name_assign_type = name_assign_type; | ||||
|  | @ -8275,9 +8326,7 @@ void free_netdev(struct net_device *dev) | |||
| 
 | ||||
| 	might_sleep(); | ||||
| 	netif_free_tx_queues(dev); | ||||
| #ifdef CONFIG_SYSFS | ||||
| 	kvfree(dev->_rx); | ||||
| #endif | ||||
| 	netif_free_rx_queues(dev); | ||||
| 
 | ||||
| 	kfree(rcu_dereference_protected(dev->ingress_queue, 1)); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jesper Dangaard Brouer
						Jesper Dangaard Brouer