-----Original Message-----
> Date: Fri, 9 Mar 2018 16:42:03 +0000
> From: Konstantin Ananyev <konstantin.anan...@intel.com>
> To: dev@dpdk.org
> CC: Konstantin Ananyev <konstantin.anan...@intel.com>
> Subject: [dpdk-dev] [PATCH v1 3/5] bpf: introduce basic RX/TX BPF filters
> X-Mailer: git-send-email 1.7.0.7
> 
> Introduce API to install BPF based filters on ethdev RX/TX path.
> Current implementation is pure SW one, based on ethdev RX/TX
> callback mechanism.
> 
> Signed-off-by: Konstantin Ananyev <konstantin.anan...@intel.com>
> ---
>  lib/librte_bpf/Makefile            |   2 +
>  lib/librte_bpf/bpf_pkt.c           | 524 
> +++++++++++++++++++++++++++++++++++++
>  lib/librte_bpf/rte_bpf_ethdev.h    |  50 ++++
>  lib/librte_bpf/rte_bpf_version.map |   4 +
>  4 files changed, 580 insertions(+)
>  create mode 100644 lib/librte_bpf/bpf_pkt.c
>  create mode 100644 lib/librte_bpf/rte_bpf_ethdev.h
> 
> diff --git a/lib/librte_bpf/Makefile b/lib/librte_bpf/Makefile
> +
> +/*
> + * information about all installed BPF rx/tx callbacks
> + */
> +
> +struct bpf_eth_cbi {
> +     uint32_t use;    /*usage counter */
> +     void *cb;        /* callback handle */
> +     struct rte_bpf *bpf;
> +     struct rte_bpf_jit jit;
> +} __rte_cache_aligned;
> +
> +/*
> + * Odd number means that callback is used by datapath.
> + * Even number means that callback is not used by datapath.
> + */
> +#define BPF_ETH_CBI_INUSE  1
> +
> +static struct bpf_eth_cbi rx_cbi[RTE_MAX_ETHPORTS][RTE_MAX_QUEUES_PER_PORT];
> +static struct bpf_eth_cbi tx_cbi[RTE_MAX_ETHPORTS][RTE_MAX_QUEUES_PER_PORT];

How about allocating this memory from huge page?

> +
> +/*
> + * Marks given callback as used by datapath.
> + */
> +static __rte_always_inline void
> +bpf_eth_cbi_inuse(struct bpf_eth_cbi *cbi)
> +{
> +     cbi->use++;
> +     /* make sure no store/load reordering could happen */
> +     rte_smp_mb();

This is an full barrier on non x86. How about a light version of this
logic? See below.

> +}
> +
> +/*
> + * Marks given callback list as not used by datapath.
> + */
> +static __rte_always_inline void
> +bpf_eth_cbi_unuse(struct bpf_eth_cbi *cbi)
> +{
> +     /* make sure all previous loads are completed */
> +     rte_smp_rmb();
> +     cbi->use++;
> +}
> +
> +/*
> + * Waits till datapath finished using given callback.
> + */
> +static void
> +bpf_eth_cbi_wait(const struct bpf_eth_cbi *cbi)
> +{
> +     uint32_t nuse, puse;
> +
> +     /* make sure all previous loads and stores are completed */
> +     rte_smp_mb();
> +

Read conjunction with below change

#if 0
> +     puse = cbi->use;
> +
> +     /* in use, busy wait till current RX/TX iteration is finished */
> +     if ((puse & BPF_ETH_CBI_INUSE) != 0) {
> +             do {
> +                     rte_pause();
> +                     rte_compiler_barrier();
> +                     nuse = cbi->use;
> +             } while (nuse == puse);
> +     }
#else
        cbi->cb = NULL;
        while (likely(cb->done != 1)) {
                rte_pause();
                rte_smb_rmb();
        }

or any other logic using flag to wait until callback completes.
#endif

> +}
> +
> +
> +/*
> + * RX/TX callbacks for raw data bpf.
> + */
> +
> +static uint16_t
> +bpf_rx_callback_vm(__rte_unused uint16_t port, __rte_unused uint16_t queue,
> +     struct rte_mbuf *pkt[], uint16_t nb_pkts,
> +     __rte_unused uint16_t max_pkts, void *user_param)
> +{
> +     struct bpf_eth_cbi *cbi;
> +     uint16_t rc;
> +
> +     cbi = user_param;
> +

Read conjunction with above change

#if 0
> +     bpf_eth_cbi_inuse(cbi);
> +     rc = (cbi->cb != NULL) ?
> +             pkt_filter_vm(cbi->bpf, pkt, nb_pkts, 1) :
> +             nb_pkts;
> +     bpf_eth_cbi_unuse(cbi);
#else
        if (likely(cbi->cb != NULL))
                return pkt_filter_vm(cbi->bpf, pkt, nb_pkts, 1) :
        else {
                cbi->done = 1;
                rte_smb_wmb();
                return nb_pkts;
        }
#endif

> +     return rc;
> +}
> +

Reply via email to