thunderx: setup xdp_rxq_info
authorJesper Dangaard Brouer <brouer@redhat.com>
Wed, 3 Jan 2018 10:25:54 +0000 (11:25 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 5 Jan 2018 23:21:21 +0000 (15:21 -0800)
This driver uses a bool scheme for "enable"/"disable" when setting up
different resources.  Thus, the hook points for xdp_rxq_info is done
in the same function call nicvf_rcv_queue_config().  This is activated
through enable/disable via nicvf_config_data_transfer(), which is tied
into nicvf_stop()/nicvf_open().

Extending driver packet handler call-path nicvf_rcv_pkt_handler() with
a pointer to the given struct rcv_queue, in-order to access the
xdp_rxq_info data area (in nicvf_xdp_rx()).

V2: Driver have no proper error path for failed XDP RX-queue info reg,
as nicvf_rcv_queue_config is a void function.

Cc: linux-arm-kernel@lists.infradead.org
Cc: Sunil Goutham <sgoutham@cavium.com>
Cc: Robert Richter <rric@kernel.org>
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
drivers/net/ethernet/cavium/thunder/nicvf_main.c
drivers/net/ethernet/cavium/thunder/nicvf_queues.c
drivers/net/ethernet/cavium/thunder/nicvf_queues.h

index 52b3a6044f85f4cf1a1ddcc920b3695664e3ed8b..21618d0d694fd8a43bc022e5894704e2e6a3bb81 100644 (file)
@@ -521,7 +521,7 @@ static void nicvf_unmap_page(struct nicvf *nic, struct page *page, u64 dma_addr)
 
 static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
                                struct cqe_rx_t *cqe_rx, struct snd_queue *sq,
-                               struct sk_buff **skb)
+                               struct rcv_queue *rq, struct sk_buff **skb)
 {
        struct xdp_buff xdp;
        struct page *page;
@@ -545,6 +545,7 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
        xdp.data = (void *)cpu_addr;
        xdp_set_data_meta_invalid(&xdp);
        xdp.data_end = xdp.data + len;
+       xdp.rxq = &rq->xdp_rxq;
        orig_data = xdp.data;
 
        rcu_read_lock();
@@ -698,7 +699,8 @@ static inline void nicvf_set_rxhash(struct net_device *netdev,
 
 static void nicvf_rcv_pkt_handler(struct net_device *netdev,
                                  struct napi_struct *napi,
-                                 struct cqe_rx_t *cqe_rx, struct snd_queue *sq)
+                                 struct cqe_rx_t *cqe_rx,
+                                 struct snd_queue *sq, struct rcv_queue *rq)
 {
        struct sk_buff *skb = NULL;
        struct nicvf *nic = netdev_priv(netdev);
@@ -724,7 +726,7 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
        /* For XDP, ignore pkts spanning multiple pages */
        if (nic->xdp_prog && (cqe_rx->rb_cnt == 1)) {
                /* Packet consumed by XDP */
-               if (nicvf_xdp_rx(snic, nic->xdp_prog, cqe_rx, sq, &skb))
+               if (nicvf_xdp_rx(snic, nic->xdp_prog, cqe_rx, sq, rq, &skb))
                        return;
        } else {
                skb = nicvf_get_rcv_skb(snic, cqe_rx,
@@ -781,6 +783,7 @@ static int nicvf_cq_intr_handler(struct net_device *netdev, u8 cq_idx,
        struct cqe_rx_t *cq_desc;
        struct netdev_queue *txq;
        struct snd_queue *sq = &qs->sq[cq_idx];
+       struct rcv_queue *rq = &qs->rq[cq_idx];
        unsigned int tx_pkts = 0, tx_bytes = 0, txq_idx;
 
        spin_lock_bh(&cq->lock);
@@ -811,7 +814,7 @@ loop:
 
                switch (cq_desc->cqe_type) {
                case CQE_TYPE_RX:
-                       nicvf_rcv_pkt_handler(netdev, napi, cq_desc, sq);
+                       nicvf_rcv_pkt_handler(netdev, napi, cq_desc, sq, rq);
                        work_done++;
                break;
                case CQE_TYPE_SEND:
index f38ea349aa00ba75f33183db076232ab206d2bb1..14e62c6ac3425829b536345cf2f7e16e06fe7db1 100644 (file)
@@ -760,6 +760,7 @@ static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs,
 
        if (!rq->enable) {
                nicvf_reclaim_rcv_queue(nic, qs, qidx);
+               xdp_rxq_info_unreg(&rq->xdp_rxq);
                return;
        }
 
@@ -772,6 +773,9 @@ static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs,
        /* all writes of RBDR data to be loaded into L2 Cache as well*/
        rq->caching = 1;
 
+       /* Driver have no proper error path for failed XDP RX-queue info reg */
+       WARN_ON(xdp_rxq_info_reg(&rq->xdp_rxq, nic->netdev, qidx) < 0);
+
        /* Send a mailbox msg to PF to config RQ */
        mbx.rq.msg = NIC_MBOX_MSG_RQ_CFG;
        mbx.rq.qs_num = qs->vnic_id;
index 178ab6e8e3c5726c22fa58f5d3a65b4e6fe7a77d..7d1e4e2aaad0c05f7e72cd0f0c5f7fa74e4bf4d8 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/netdevice.h>
 #include <linux/iommu.h>
 #include <linux/bpf.h>
+#include <net/xdp.h>
 #include "q_struct.h"
 
 #define MAX_QUEUE_SET                  128
@@ -255,6 +256,7 @@ struct rcv_queue {
        u8              start_qs_rbdr_idx; /* RBDR idx in the above QS */
        u8              caching;
        struct          rx_tx_queue_stats stats;
+       struct xdp_rxq_info xdp_rxq;
 } ____cacheline_aligned_in_smp;
 
 struct cmp_queue {