netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC net-next 0/8] xdp: offload mode
@ 2017-06-16 23:57 Jakub Kicinski
  2017-06-16 23:57 ` [RFC net-next 1/8] xdp: pass XDP flags into install handlers Jakub Kicinski
                   ` (7 more replies)
  0 siblings, 8 replies; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-16 23:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kafai, daniel, netoptimizer, oss-drivers, Jakub Kicinski

Hi!

This set adds XDP flag for forcing offload and a attachement mode
for reporting to user space that program has been offloaded.  The
nfp driver is modified to make use of the new flags, but also to
adhere to the DRV_MODE flag which should disable the HW offload.

Note that the NFP driver currently claims XDP offload support but 
lacks most basic features like direct packet access.

Jakub Kicinski (8):
  xdp: pass XDP flags into install handlers
  xdp: add HW offload mode flag for installing programs
  nfp: xdp: move driver XDP setup into a separate function
  nfp: bpf: don't offload XDP programs in DRV_MODE
  nfp: bpf: take a reference on offloaded programs
  nfp: bpf: add support for XDP_FLAGS_HW_MODE
  xdp: add reporting of offload mode
  nfp: xdp: report if program is offloaded

 drivers/net/ethernet/netronome/nfp/nfp_net.h       |  5 ++
 .../net/ethernet/netronome/nfp/nfp_net_common.c    | 53 ++++++++++++++++------
 include/linux/netdevice.h                          |  8 ++--
 include/uapi/linux/if_link.h                       |  8 +++-
 net/core/dev.c                                     | 10 ++--
 net/core/rtnetlink.c                               | 10 ++--
 6 files changed, 66 insertions(+), 28 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC net-next 1/8] xdp: pass XDP flags into install handlers
  2017-06-16 23:57 [RFC net-next 0/8] xdp: offload mode Jakub Kicinski
@ 2017-06-16 23:57 ` Jakub Kicinski
  2017-06-19 23:38   ` Daniel Borkmann
  2017-06-16 23:57 ` [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs Jakub Kicinski
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-16 23:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kafai, daniel, netoptimizer, oss-drivers, Jakub Kicinski

Pass XDP flags to the xdp ndo.  This will allow drivers to look
at the mode flags and make decisions about offload.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 include/linux/netdevice.h | 1 +
 net/core/dev.c            | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7c7118b3bd69..b194817631de 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -820,6 +820,7 @@ struct netdev_xdp {
 	union {
 		/* XDP_SETUP_PROG */
 		struct {
+			u32 flags;
 			struct bpf_prog *prog;
 			struct netlink_ext_ack *extack;
 		};
diff --git a/net/core/dev.c b/net/core/dev.c
index b8d6dd9e8b5c..a04db264aa1c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6953,7 +6953,7 @@ bool __dev_xdp_attached(struct net_device *dev, xdp_op_t xdp_op,
 }
 
 static int dev_xdp_install(struct net_device *dev, xdp_op_t xdp_op,
-			   struct netlink_ext_ack *extack,
+			   struct netlink_ext_ack *extack, u32 flags,
 			   struct bpf_prog *prog)
 {
 	struct netdev_xdp xdp;
@@ -6961,6 +6961,7 @@ static int dev_xdp_install(struct net_device *dev, xdp_op_t xdp_op,
 	memset(&xdp, 0, sizeof(xdp));
 	xdp.command = XDP_SETUP_PROG;
 	xdp.extack = extack;
+	xdp.flags = flags;
 	xdp.prog = prog;
 
 	return xdp_op(dev, &xdp);
@@ -7005,7 +7006,7 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
 			return PTR_ERR(prog);
 	}
 
-	err = dev_xdp_install(dev, xdp_op, extack, prog);
+	err = dev_xdp_install(dev, xdp_op, extack, flags, prog);
 	if (err < 0 && prog)
 		bpf_prog_put(prog);
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs
  2017-06-16 23:57 [RFC net-next 0/8] xdp: offload mode Jakub Kicinski
  2017-06-16 23:57 ` [RFC net-next 1/8] xdp: pass XDP flags into install handlers Jakub Kicinski
@ 2017-06-16 23:57 ` Jakub Kicinski
  2017-06-19 22:55   ` Daniel Borkmann
  2017-06-19 23:39   ` Daniel Borkmann
  2017-06-16 23:57 ` [RFC net-next 3/8] nfp: xdp: move driver XDP setup into a separate function Jakub Kicinski
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-16 23:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kafai, daniel, netoptimizer, oss-drivers, Jakub Kicinski

Add an installation-time flag for requesting that the program
be installed only if it can be offloaded to HW.

Internally new command for ndo_xdp is added, this way we avoid
putting checks into drivers since they all return -EINVAL on
an unknown command.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 include/linux/netdevice.h    | 1 +
 include/uapi/linux/if_link.h | 7 +++++--
 net/core/dev.c               | 7 +++++--
 net/core/rtnetlink.c         | 4 ++--
 4 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b194817631de..a838591aad28 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -807,6 +807,7 @@ enum xdp_netdev_command {
 	 * when it is no longer used.
 	 */
 	XDP_SETUP_PROG,
+	XDP_SETUP_PROG_HW,
 	/* Check if a bpf program is set on the device.  The callee should
 	 * return true if a program is currently attached and running.
 	 */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index dd88375a6580..ce777ec88e1e 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -891,9 +891,12 @@ enum {
 #define XDP_FLAGS_UPDATE_IF_NOEXIST	(1U << 0)
 #define XDP_FLAGS_SKB_MODE		(1U << 1)
 #define XDP_FLAGS_DRV_MODE		(1U << 2)
+#define XDP_FLAGS_HW_MODE		(1U << 3)
+#define XDP_FLAGS_MODES			(XDP_FLAGS_SKB_MODE | \
+					 XDP_FLAGS_DRV_MODE | \
+					 XDP_FLAGS_HW_MODE)
 #define XDP_FLAGS_MASK			(XDP_FLAGS_UPDATE_IF_NOEXIST | \
-					 XDP_FLAGS_SKB_MODE | \
-					 XDP_FLAGS_DRV_MODE)
+					 XDP_FLAGS_MODES)
 
 /* These are stored into IFLA_XDP_ATTACHED on dump. */
 enum {
diff --git a/net/core/dev.c b/net/core/dev.c
index a04db264aa1c..05cec8e2cd82 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6959,7 +6959,10 @@ static int dev_xdp_install(struct net_device *dev, xdp_op_t xdp_op,
 	struct netdev_xdp xdp;
 
 	memset(&xdp, 0, sizeof(xdp));
-	xdp.command = XDP_SETUP_PROG;
+	if (flags & XDP_FLAGS_HW_MODE)
+		xdp.command = XDP_SETUP_PROG_HW;
+	else
+		xdp.command = XDP_SETUP_PROG;
 	xdp.extack = extack;
 	xdp.flags = flags;
 	xdp.prog = prog;
@@ -6987,7 +6990,7 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
 	ASSERT_RTNL();
 
 	xdp_op = xdp_chk = ops->ndo_xdp;
-	if (!xdp_op && (flags & XDP_FLAGS_DRV_MODE))
+	if (!xdp_op && (flags & (XDP_FLAGS_DRV_MODE | XDP_FLAGS_HW_MODE)))
 		return -EOPNOTSUPP;
 	if (!xdp_op || (flags & XDP_FLAGS_SKB_MODE))
 		xdp_op = generic_xdp_install;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 3aa57848a895..daf3b39be649 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -16,6 +16,7 @@
  *	Vitaly E. Lavrov		RTA_OK arithmetics was wrong.
  */
 
+#include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -2251,8 +2252,7 @@ static int do_setlink(const struct sk_buff *skb,
 				err = -EINVAL;
 				goto errout;
 			}
-			if ((xdp_flags & XDP_FLAGS_SKB_MODE) &&
-			    (xdp_flags & XDP_FLAGS_DRV_MODE)) {
+			if (hweight32(xdp_flags & XDP_FLAGS_MODES) > 1) {
 				err = -EINVAL;
 				goto errout;
 			}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC net-next 3/8] nfp: xdp: move driver XDP setup into a separate function
  2017-06-16 23:57 [RFC net-next 0/8] xdp: offload mode Jakub Kicinski
  2017-06-16 23:57 ` [RFC net-next 1/8] xdp: pass XDP flags into install handlers Jakub Kicinski
  2017-06-16 23:57 ` [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs Jakub Kicinski
@ 2017-06-16 23:57 ` Jakub Kicinski
  2017-06-16 23:57 ` [RFC net-next 4/8] nfp: bpf: don't offload XDP programs in DRV_MODE Jakub Kicinski
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-16 23:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kafai, daniel, netoptimizer, oss-drivers, Jakub Kicinski

In preparation of XDP offload flags move the driver setup into
a function.  Otherwise the number of conditions in one function
would make it slightly hard to follow.  The offload handler may
now be called with NULL prog, even if no offload is currently
active, but that's fine, offload code can handle that.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_common.c    | 23 +++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 2bdddd1ae666..f2188b9c3628 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3274,10 +3274,11 @@ static void nfp_net_del_vxlan_port(struct net_device *netdev,
 		nfp_net_set_vxlan_port(nn, idx, 0);
 }
 
-static int nfp_net_xdp_setup(struct nfp_net *nn, struct netdev_xdp *xdp)
+static int
+nfp_net_xdp_setup_drv(struct nfp_net *nn, struct bpf_prog *prog,
+		      struct netlink_ext_ack *extack)
 {
 	struct bpf_prog *old_prog = nn->dp.xdp_prog;
-	struct bpf_prog *prog = xdp->prog;
 	struct nfp_net_dp *dp;
 	int err;
 
@@ -3286,7 +3287,6 @@ static int nfp_net_xdp_setup(struct nfp_net *nn, struct netdev_xdp *xdp)
 	if (prog && nn->dp.xdp_prog) {
 		prog = xchg(&nn->dp.xdp_prog, prog);
 		bpf_prog_put(prog);
-		nfp_app_xdp_offload(nn->app, nn, nn->dp.xdp_prog);
 		return 0;
 	}
 
@@ -3300,13 +3300,26 @@ static int nfp_net_xdp_setup(struct nfp_net *nn, struct netdev_xdp *xdp)
 	dp->rx_dma_off = prog ? XDP_PACKET_HEADROOM - nn->dp.rx_offset : 0;
 
 	/* We need RX reconfig to remap the buffers (BIDIR vs FROM_DEV) */
-	err = nfp_net_ring_reconfig(nn, dp, xdp->extack);
+	err = nfp_net_ring_reconfig(nn, dp, extack);
 	if (err)
 		return err;
 
 	if (old_prog)
 		bpf_prog_put(old_prog);
 
+	return 0;
+}
+
+static int
+nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog,
+		  struct netlink_ext_ack *extack)
+{
+	int err;
+
+	err = nfp_net_xdp_setup_drv(nn, prog, extack);
+	if (err)
+		return err;
+
 	nfp_app_xdp_offload(nn->app, nn, nn->dp.xdp_prog);
 
 	return 0;
@@ -3318,7 +3331,7 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_xdp *xdp)
 
 	switch (xdp->command) {
 	case XDP_SETUP_PROG:
-		return nfp_net_xdp_setup(nn, xdp);
+		return nfp_net_xdp_setup(nn, xdp->prog, xdp->extack);
 	case XDP_QUERY_PROG:
 		xdp->prog_attached = !!nn->dp.xdp_prog;
 		xdp->prog_id = nn->dp.xdp_prog ? nn->dp.xdp_prog->aux->id : 0;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC net-next 4/8] nfp: bpf: don't offload XDP programs in DRV_MODE
  2017-06-16 23:57 [RFC net-next 0/8] xdp: offload mode Jakub Kicinski
                   ` (2 preceding siblings ...)
  2017-06-16 23:57 ` [RFC net-next 3/8] nfp: xdp: move driver XDP setup into a separate function Jakub Kicinski
@ 2017-06-16 23:57 ` Jakub Kicinski
  2017-06-16 23:57 ` [RFC net-next 5/8] nfp: bpf: take a reference on offloaded programs Jakub Kicinski
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-16 23:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kafai, daniel, netoptimizer, oss-drivers, Jakub Kicinski

DRV_MODE means that user space wants the program to be run in
the driver.  Do not try to offload.  Only offload if no mode
flags have been specified.

Remember what the mode is when the program is installed and refuse
new setup requests if there is already a program loaded in a
different mode.  This should leave it open for us to implement
simultaneous loading of two programs - one in the drv path and
another to the NIC later.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net.h        |  3 +++
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 14 +++++++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index 02fd8d4e253c..7952fbfb94d6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -541,6 +541,7 @@ struct nfp_net_dp {
  * @rss_cfg:            RSS configuration
  * @rss_key:            RSS secret key
  * @rss_itbl:           RSS indirection table
+ * @xdp_flags:		Flags with which XDP prog was loaded
  * @max_r_vecs:		Number of allocated interrupt vectors for RX/TX
  * @max_tx_rings:       Maximum number of TX rings supported by the Firmware
  * @max_rx_rings:       Maximum number of RX rings supported by the Firmware
@@ -590,6 +591,8 @@ struct nfp_net {
 	u8 rss_key[NFP_NET_CFG_RSS_KEY_SZ];
 	u8 rss_itbl[NFP_NET_CFG_RSS_ITBL_SZ];
 
+	u32 xdp_flags;
+
 	unsigned int max_tx_rings;
 	unsigned int max_rx_rings;
 
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index f2188b9c3628..9563615cf4b7 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3311,16 +3311,23 @@ nfp_net_xdp_setup_drv(struct nfp_net *nn, struct bpf_prog *prog,
 }
 
 static int
-nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog,
+nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog, u32 flags,
 		  struct netlink_ext_ack *extack)
 {
+	struct bpf_prog *offload_prog;
 	int err;
 
+	if (nn->dp.xdp_prog && (flags ^ nn->xdp_flags) & XDP_FLAGS_MODES)
+		return -EBUSY;
+
+	offload_prog = flags & XDP_FLAGS_DRV_MODE ? NULL : prog;
+
 	err = nfp_net_xdp_setup_drv(nn, prog, extack);
 	if (err)
 		return err;
 
-	nfp_app_xdp_offload(nn->app, nn, nn->dp.xdp_prog);
+	nfp_app_xdp_offload(nn->app, nn, offload_prog);
+	nn->xdp_flags = flags;
 
 	return 0;
 }
@@ -3331,7 +3338,8 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_xdp *xdp)
 
 	switch (xdp->command) {
 	case XDP_SETUP_PROG:
-		return nfp_net_xdp_setup(nn, xdp->prog, xdp->extack);
+		return nfp_net_xdp_setup(nn, xdp->prog, xdp->flags,
+					 xdp->extack);
 	case XDP_QUERY_PROG:
 		xdp->prog_attached = !!nn->dp.xdp_prog;
 		xdp->prog_id = nn->dp.xdp_prog ? nn->dp.xdp_prog->aux->id : 0;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC net-next 5/8] nfp: bpf: take a reference on offloaded programs
  2017-06-16 23:57 [RFC net-next 0/8] xdp: offload mode Jakub Kicinski
                   ` (3 preceding siblings ...)
  2017-06-16 23:57 ` [RFC net-next 4/8] nfp: bpf: don't offload XDP programs in DRV_MODE Jakub Kicinski
@ 2017-06-16 23:57 ` Jakub Kicinski
  2017-06-19 23:23   ` Daniel Borkmann
  2017-06-16 23:57 ` [RFC net-next 6/8] nfp: bpf: add support for XDP_FLAGS_HW_MODE Jakub Kicinski
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-16 23:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kafai, daniel, netoptimizer, oss-drivers, Jakub Kicinski

The xdp_prog member of the adapter's data path structure is used
for XDP in driver mode.  In case a XDP program is loaded with in
HW-only mode, we need to store it somewhere else.  Add a new XDP
prog pointer in the main structure and use that when we need to
know whether any XDP program is loaded, not only a driver mode
one.  Only release our reference on adapter free instead of
immediately after netdev unregister to allow offload to be disabled
first.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net.h        |  2 ++
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 20 ++++++++++----------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index 7952fbfb94d6..b7446793106d 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -542,6 +542,7 @@ struct nfp_net_dp {
  * @rss_key:            RSS secret key
  * @rss_itbl:           RSS indirection table
  * @xdp_flags:		Flags with which XDP prog was loaded
+ * @xdp_prog:		XDP prog (for ctrl path, both DRV and HW modes)
  * @max_r_vecs:		Number of allocated interrupt vectors for RX/TX
  * @max_tx_rings:       Maximum number of TX rings supported by the Firmware
  * @max_rx_rings:       Maximum number of RX rings supported by the Firmware
@@ -592,6 +593,7 @@ struct nfp_net {
 	u8 rss_itbl[NFP_NET_CFG_RSS_ITBL_SZ];
 
 	u32 xdp_flags;
+	struct bpf_prog *xdp_prog;
 
 	unsigned int max_tx_rings;
 	unsigned int max_rx_rings;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 9563615cf4b7..68648e312129 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3278,7 +3278,6 @@ static int
 nfp_net_xdp_setup_drv(struct nfp_net *nn, struct bpf_prog *prog,
 		      struct netlink_ext_ack *extack)
 {
-	struct bpf_prog *old_prog = nn->dp.xdp_prog;
 	struct nfp_net_dp *dp;
 	int err;
 
@@ -3304,9 +3303,6 @@ nfp_net_xdp_setup_drv(struct nfp_net *nn, struct bpf_prog *prog,
 	if (err)
 		return err;
 
-	if (old_prog)
-		bpf_prog_put(old_prog);
-
 	return 0;
 }
 
@@ -3317,7 +3313,7 @@ nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog, u32 flags,
 	struct bpf_prog *offload_prog;
 	int err;
 
-	if (nn->dp.xdp_prog && (flags ^ nn->xdp_flags) & XDP_FLAGS_MODES)
+	if (nn->xdp_prog && (flags ^ nn->xdp_flags) & XDP_FLAGS_MODES)
 		return -EBUSY;
 
 	offload_prog = flags & XDP_FLAGS_DRV_MODE ? NULL : prog;
@@ -3327,6 +3323,10 @@ nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog, u32 flags,
 		return err;
 
 	nfp_app_xdp_offload(nn->app, nn, offload_prog);
+
+	if (nn->xdp_prog)
+		bpf_prog_put(nn->xdp_prog);
+	nn->xdp_prog = prog;
 	nn->xdp_flags = flags;
 
 	return 0;
@@ -3341,8 +3341,8 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_xdp *xdp)
 		return nfp_net_xdp_setup(nn, xdp->prog, xdp->flags,
 					 xdp->extack);
 	case XDP_QUERY_PROG:
-		xdp->prog_attached = !!nn->dp.xdp_prog;
-		xdp->prog_id = nn->dp.xdp_prog ? nn->dp.xdp_prog->aux->id : 0;
+		xdp->prog_attached = !!nn->xdp_prog;
+		xdp->prog_id = nn->xdp_prog ? nn->xdp_prog->aux->id : 0;
 		return 0;
 	default:
 		return -EINVAL;
@@ -3500,6 +3500,9 @@ struct nfp_net *nfp_net_alloc(struct pci_dev *pdev, bool needs_netdev,
  */
 void nfp_net_free(struct nfp_net *nn)
 {
+	if (nn->xdp_prog)
+		bpf_prog_put(nn->xdp_prog);
+
 	if (nn->dp.netdev)
 		free_netdev(nn->dp.netdev);
 	else
@@ -3757,7 +3760,4 @@ void nfp_net_clean(struct nfp_net *nn)
 		return;
 
 	unregister_netdev(nn->dp.netdev);
-
-	if (nn->dp.xdp_prog)
-		bpf_prog_put(nn->dp.xdp_prog);
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC net-next 6/8] nfp: bpf: add support for XDP_FLAGS_HW_MODE
  2017-06-16 23:57 [RFC net-next 0/8] xdp: offload mode Jakub Kicinski
                   ` (4 preceding siblings ...)
  2017-06-16 23:57 ` [RFC net-next 5/8] nfp: bpf: take a reference on offloaded programs Jakub Kicinski
@ 2017-06-16 23:57 ` Jakub Kicinski
  2017-06-19 23:50   ` Daniel Borkmann
  2017-06-16 23:57 ` [RFC net-next 7/8] xdp: add reporting of offload mode Jakub Kicinski
  2017-06-16 23:57 ` [RFC net-next 8/8] nfp: xdp: report if program is offloaded Jakub Kicinski
  7 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-16 23:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kafai, daniel, netoptimizer, oss-drivers, Jakub Kicinski

Respect the XDP_FLAGS_HW_MODE.  When it's set install the program
on the NIC and skip enabling XDP in the driver.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 68648e312129..c5903b6e58c5 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3310,19 +3310,22 @@ static int
 nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog, u32 flags,
 		  struct netlink_ext_ack *extack)
 {
-	struct bpf_prog *offload_prog;
+	struct bpf_prog *drv_prog, *offload_prog;
 	int err;
 
 	if (nn->xdp_prog && (flags ^ nn->xdp_flags) & XDP_FLAGS_MODES)
 		return -EBUSY;
 
+	drv_prog     = flags & XDP_FLAGS_HW_MODE  ? NULL : prog;
 	offload_prog = flags & XDP_FLAGS_DRV_MODE ? NULL : prog;
 
-	err = nfp_net_xdp_setup_drv(nn, prog, extack);
+	err = nfp_net_xdp_setup_drv(nn, drv_prog, extack);
 	if (err)
 		return err;
 
-	nfp_app_xdp_offload(nn->app, nn, offload_prog);
+	err = nfp_app_xdp_offload(nn->app, nn, offload_prog);
+	if (err && flags & XDP_FLAGS_HW_MODE)
+		return err;
 
 	if (nn->xdp_prog)
 		bpf_prog_put(nn->xdp_prog);
@@ -3338,6 +3341,7 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_xdp *xdp)
 
 	switch (xdp->command) {
 	case XDP_SETUP_PROG:
+	case XDP_SETUP_PROG_HW:
 		return nfp_net_xdp_setup(nn, xdp->prog, xdp->flags,
 					 xdp->extack);
 	case XDP_QUERY_PROG:
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC net-next 7/8] xdp: add reporting of offload mode
  2017-06-16 23:57 [RFC net-next 0/8] xdp: offload mode Jakub Kicinski
                   ` (5 preceding siblings ...)
  2017-06-16 23:57 ` [RFC net-next 6/8] nfp: bpf: add support for XDP_FLAGS_HW_MODE Jakub Kicinski
@ 2017-06-16 23:57 ` Jakub Kicinski
  2017-06-19 23:40   ` Daniel Borkmann
  2017-06-16 23:57 ` [RFC net-next 8/8] nfp: xdp: report if program is offloaded Jakub Kicinski
  7 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-16 23:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kafai, daniel, netoptimizer, oss-drivers, Jakub Kicinski

Extend the XDP_ATTACHED_* values to include offloaded mode.
Let drivers report whether program is installed in the driver
or the HW by changing the prog_attached field from bool to
u8 (type of the netlink attribute).

Exploit the fact that the value of XDP_ATTACHED_DRV is 1,
therefore since all drivers currently assign the mode with
double negation:
       mode = !!xdp_prog;
no drivers have to be modified.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 include/linux/netdevice.h    | 7 ++++---
 include/uapi/linux/if_link.h | 1 +
 net/core/dev.c               | 3 +--
 net/core/rtnetlink.c         | 6 +++---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index a838591aad28..68f5d899d1e6 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -809,7 +809,8 @@ enum xdp_netdev_command {
 	XDP_SETUP_PROG,
 	XDP_SETUP_PROG_HW,
 	/* Check if a bpf program is set on the device.  The callee should
-	 * return true if a program is currently attached and running.
+	 * set @prog_attached to one of XDP_ATTACHED_* values, note that "true"
+	 * is equivalent to XDP_ATTACHED_DRV.
 	 */
 	XDP_QUERY_PROG,
 };
@@ -827,7 +828,7 @@ struct netdev_xdp {
 		};
 		/* XDP_QUERY_PROG */
 		struct {
-			bool prog_attached;
+			u8 prog_attached;
 			u32 prog_id;
 		};
 	};
@@ -3307,7 +3308,7 @@ struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 typedef int (*xdp_op_t)(struct net_device *dev, struct netdev_xdp *xdp);
 int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
 		      int fd, u32 flags);
-bool __dev_xdp_attached(struct net_device *dev, xdp_op_t xdp_op, u32 *prog_id);
+u8 __dev_xdp_attached(struct net_device *dev, xdp_op_t xdp_op, u32 *prog_id);
 
 int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
 int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index ce777ec88e1e..8d062c58d5cb 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -903,6 +903,7 @@ enum {
 	XDP_ATTACHED_NONE = 0,
 	XDP_ATTACHED_DRV,
 	XDP_ATTACHED_SKB,
+	XDP_ATTACHED_HW,
 };
 
 enum {
diff --git a/net/core/dev.c b/net/core/dev.c
index 05cec8e2cd82..ad1ecb26e9fa 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6936,8 +6936,7 @@ int dev_change_proto_down(struct net_device *dev, bool proto_down)
 }
 EXPORT_SYMBOL(dev_change_proto_down);
 
-bool __dev_xdp_attached(struct net_device *dev, xdp_op_t xdp_op,
-			u32 *prog_id)
+u8 __dev_xdp_attached(struct net_device *dev, xdp_op_t xdp_op, u32 *prog_id)
 {
 	struct netdev_xdp xdp;
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index daf3b39be649..f0f5b418e52d 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1264,10 +1264,10 @@ static u8 rtnl_xdp_attached_mode(struct net_device *dev, u32 *prog_id)
 		*prog_id = generic_xdp_prog->aux->id;
 		return XDP_ATTACHED_SKB;
 	}
-	if (ops->ndo_xdp && __dev_xdp_attached(dev, ops->ndo_xdp, prog_id))
-		return XDP_ATTACHED_DRV;
+	if (!ops->ndo_xdp)
+		return XDP_ATTACHED_NONE;
 
-	return XDP_ATTACHED_NONE;
+	return __dev_xdp_attached(dev, ops->ndo_xdp, prog_id);
 }
 
 static int rtnl_xdp_fill(struct sk_buff *skb, struct net_device *dev)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC net-next 8/8] nfp: xdp: report if program is offloaded
  2017-06-16 23:57 [RFC net-next 0/8] xdp: offload mode Jakub Kicinski
                   ` (6 preceding siblings ...)
  2017-06-16 23:57 ` [RFC net-next 7/8] xdp: add reporting of offload mode Jakub Kicinski
@ 2017-06-16 23:57 ` Jakub Kicinski
  7 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-16 23:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kafai, daniel, netoptimizer, oss-drivers, Jakub Kicinski

Make use of just added XDP_ATTACHED_HW.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index c5903b6e58c5..cabd117303e1 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3346,6 +3346,8 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_xdp *xdp)
 					 xdp->extack);
 	case XDP_QUERY_PROG:
 		xdp->prog_attached = !!nn->xdp_prog;
+		if (nn->dp.bpf_offload_xdp)
+			xdp->prog_attached = XDP_ATTACHED_HW;
 		xdp->prog_id = nn->xdp_prog ? nn->xdp_prog->aux->id : 0;
 		return 0;
 	default:
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs
  2017-06-16 23:57 ` [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs Jakub Kicinski
@ 2017-06-19 22:55   ` Daniel Borkmann
  2017-06-19 23:24     ` Jakub Kicinski
  2017-06-19 23:39   ` Daniel Borkmann
  1 sibling, 1 reply; 20+ messages in thread
From: Daniel Borkmann @ 2017-06-19 22:55 UTC (permalink / raw)
  To: Jakub Kicinski, netdev; +Cc: davem, kafai, netoptimizer, oss-drivers

On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
> Add an installation-time flag for requesting that the program
> be installed only if it can be offloaded to HW.
>
> Internally new command for ndo_xdp is added, this way we avoid
> putting checks into drivers since they all return -EINVAL on
> an unknown command.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
[...]
> diff --git a/net/core/dev.c b/net/core/dev.c
> index a04db264aa1c..05cec8e2cd82 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -6959,7 +6959,10 @@ static int dev_xdp_install(struct net_device *dev, xdp_op_t xdp_op,
>   	struct netdev_xdp xdp;
>
>   	memset(&xdp, 0, sizeof(xdp));
> -	xdp.command = XDP_SETUP_PROG;
> +	if (flags & XDP_FLAGS_HW_MODE)
> +		xdp.command = XDP_SETUP_PROG_HW;
> +	else
> +		xdp.command = XDP_SETUP_PROG;
>   	xdp.extack = extack;
>   	xdp.flags = flags;
>   	xdp.prog = prog;

One thing I'm not sure I follow is that while you pass flags to the ndo
in patch 1, add a new XDP_SETUP_PROG_HW command here in patch 2 based on
the flags, and later on in patch 6, you don't really make use of it, but
look at the flags anyway? Then, why adding separate XDP_SETUP_PROG_HW
in the first place?

[patch 6:]
@@ -3338,6 +3341,7 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_xdp *xdp)

  	switch (xdp->command) {
  	case XDP_SETUP_PROG:
+	case XDP_SETUP_PROG_HW:
  		return nfp_net_xdp_setup(nn, xdp->prog, xdp->flags,
  					 xdp->extack);

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 5/8] nfp: bpf: take a reference on offloaded programs
  2017-06-16 23:57 ` [RFC net-next 5/8] nfp: bpf: take a reference on offloaded programs Jakub Kicinski
@ 2017-06-19 23:23   ` Daniel Borkmann
  2017-06-19 23:34     ` Jakub Kicinski
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Borkmann @ 2017-06-19 23:23 UTC (permalink / raw)
  To: Jakub Kicinski, netdev; +Cc: davem, kafai, netoptimizer, oss-drivers

On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
> The xdp_prog member of the adapter's data path structure is used
> for XDP in driver mode.  In case a XDP program is loaded with in
> HW-only mode, we need to store it somewhere else.  Add a new XDP
> prog pointer in the main structure and use that when we need to
> know whether any XDP program is loaded, not only a driver mode
> one.  Only release our reference on adapter free instead of
> immediately after netdev unregister to allow offload to be disabled
> first.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
[...]
> @@ -3327,6 +3323,10 @@ nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog, u32 flags,
>   		return err;
>
>   	nfp_app_xdp_offload(nn->app, nn, offload_prog);
> +
> +	if (nn->xdp_prog)
> +		bpf_prog_put(nn->xdp_prog);
> +	nn->xdp_prog = prog;
>   	nn->xdp_flags = flags;
>
>   	return 0;

Can you elaborate on the extra reference on the prog? So in
nfp_net_xdp_setup(), assuming a prog was already loaded on
driver side: after your set, nfp_net_xdp_setup_drv() will then
do the xchg() on nn->dp.xdp_prog, bpf_prog_put() this one and
later back in nfp_net_xdp_setup() we check nn->xdp_prog and
bpf_prog_put() it if it existed before and update nn->xdp_prog
to the current prog. So you end up with two puts on the same
program, but I don't see where you take the one additional ref
aside from the ref that you already get from dev_change_xdp_fd().
What am I missing?

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs
  2017-06-19 22:55   ` Daniel Borkmann
@ 2017-06-19 23:24     ` Jakub Kicinski
  2017-06-19 23:36       ` Daniel Borkmann
  0 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-19 23:24 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: netdev, davem, kafai, oss-drivers, brouer

On Tue, 20 Jun 2017 00:55:41 +0200, Daniel Borkmann wrote:
> On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
> > Add an installation-time flag for requesting that the program
> > be installed only if it can be offloaded to HW.
> >
> > Internally new command for ndo_xdp is added, this way we avoid
> > putting checks into drivers since they all return -EINVAL on
> > an unknown command.
> >
> > Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>  
> [...]
> > diff --git a/net/core/dev.c b/net/core/dev.c
> > index a04db264aa1c..05cec8e2cd82 100644
> > --- a/net/core/dev.c
> > +++ b/net/core/dev.c
> > @@ -6959,7 +6959,10 @@ static int dev_xdp_install(struct net_device *dev, xdp_op_t xdp_op,
> >   	struct netdev_xdp xdp;
> >
> >   	memset(&xdp, 0, sizeof(xdp));
> > -	xdp.command = XDP_SETUP_PROG;
> > +	if (flags & XDP_FLAGS_HW_MODE)
> > +		xdp.command = XDP_SETUP_PROG_HW;
> > +	else
> > +		xdp.command = XDP_SETUP_PROG;
> >   	xdp.extack = extack;
> >   	xdp.flags = flags;
> >   	xdp.prog = prog;  
> 
> One thing I'm not sure I follow is that while you pass flags to the ndo
> in patch 1, add a new XDP_SETUP_PROG_HW command here in patch 2 based on
> the flags, and later on in patch 6, you don't really make use of it, but
> look at the flags anyway? Then, why adding separate XDP_SETUP_PROG_HW
> in the first place?
> 
> [patch 6:]
> @@ -3338,6 +3341,7 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_xdp *xdp)
> 
>   	switch (xdp->command) {
>   	case XDP_SETUP_PROG:
> +	case XDP_SETUP_PROG_HW:
>   		return nfp_net_xdp_setup(nn, xdp->prog, xdp->flags,
>   					 xdp->extack);

We still need the flags to be able to differentiate between default/no
flags case where we load to the driver and the HW ("both"), and when
the DRV_MODE flag is set, in which case we disable the HW offload and
only load to the driver.  We have three cases:

           drv     offload
 no flag   yes    attempted
DRV_MODE   yes        no
 HW_MODE    no       yes

The XDP_SETUP_PROG_HW command is purely for convenience of drivers
without an offload.  I felt it's not appropriate to burden all drivers
with:

if (xdp->flags & XDP_FLAGS_HW_MODE)
	return -EOPNOTSUPP;

But, I do have a patch which does it, so I'm happy to drop the new
command if it's preferred.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 5/8] nfp: bpf: take a reference on offloaded programs
  2017-06-19 23:23   ` Daniel Borkmann
@ 2017-06-19 23:34     ` Jakub Kicinski
  0 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-19 23:34 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: netdev, davem, kafai, brouer, oss-drivers

On Tue, 20 Jun 2017 01:23:05 +0200, Daniel Borkmann wrote:
> On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
> > The xdp_prog member of the adapter's data path structure is used
> > for XDP in driver mode.  In case a XDP program is loaded with in
> > HW-only mode, we need to store it somewhere else.  Add a new XDP
> > prog pointer in the main structure and use that when we need to
> > know whether any XDP program is loaded, not only a driver mode
> > one.  Only release our reference on adapter free instead of
> > immediately after netdev unregister to allow offload to be disabled
> > first.
> >
> > Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>  
> [...]
> > @@ -3327,6 +3323,10 @@ nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog 
> >   		return err;
> >
> >   	nfp_app_xdp_offload(nn->app, nn, offload_prog);
> > +
> > +	if (nn->xdp_prog)
> > +		bpf_prog_put(nn->xdp_prog);
> > +	nn->xdp_prog = prog;
> >   	nn->xdp_flags = flags;
> >
> >   	return 0;  
> 
> Can you elaborate on the extra reference on the prog? 

Sorry, this patch went through a few revisions and the subject doesn't
express the intent too well any more :S  Originally it was about making
sure we have a reference on the program when it's offloaded but not
loaded in the driver, but I realized the we have the reference from 
dev_change_xdp_fd() already, so now the patch just releases the
reference on the offloaded program.

> So in nfp_net_xdp_setup(), assuming a prog was already loaded on
> driver side: after your set, nfp_net_xdp_setup_drv() will then
> do the xchg() on nn->dp.xdp_prog, bpf_prog_put() this one and
> later back in nfp_net_xdp_setup() we check nn->xdp_prog and
> bpf_prog_put() it if it existed before and update nn->xdp_prog
> to the current prog. So you end up with two puts on the same
> program, but I don't see where you take the one additional ref
> aside from the ref that you already get from dev_change_xdp_fd().
> What am I missing?

You are right, I missed there were two spots where I was doing a
bpf_prog_put() in nfp_net_xdp_setup_drv(), thanks!

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs
  2017-06-19 23:24     ` Jakub Kicinski
@ 2017-06-19 23:36       ` Daniel Borkmann
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Borkmann @ 2017-06-19 23:36 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev, davem, kafai, oss-drivers, brouer

On 06/20/2017 01:24 AM, Jakub Kicinski wrote:
[...]
> The XDP_SETUP_PROG_HW command is purely for convenience of drivers
> without an offload.  I felt it's not appropriate to burden all drivers
> with:
>
> if (xdp->flags & XDP_FLAGS_HW_MODE)
> 	return -EOPNOTSUPP;
>
> But, I do have a patch which does it, so I'm happy to drop the new
> command if it's preferred.

Ahh, that makes sense, yep. I was only focused on reviewing this in
the context of nfp driver. Lack of coffee. ;)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 1/8] xdp: pass XDP flags into install handlers
  2017-06-16 23:57 ` [RFC net-next 1/8] xdp: pass XDP flags into install handlers Jakub Kicinski
@ 2017-06-19 23:38   ` Daniel Borkmann
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Borkmann @ 2017-06-19 23:38 UTC (permalink / raw)
  To: Jakub Kicinski, netdev; +Cc: davem, kafai, netoptimizer, oss-drivers

On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
> Pass XDP flags to the xdp ndo.  This will allow drivers to look
> at the mode flags and make decisions about offload.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

Acked-by: Daniel Borkmann <daniel@iogearbox.net>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs
  2017-06-16 23:57 ` [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs Jakub Kicinski
  2017-06-19 22:55   ` Daniel Borkmann
@ 2017-06-19 23:39   ` Daniel Borkmann
  1 sibling, 0 replies; 20+ messages in thread
From: Daniel Borkmann @ 2017-06-19 23:39 UTC (permalink / raw)
  To: Jakub Kicinski, netdev; +Cc: davem, kafai, netoptimizer, oss-drivers

On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
> Add an installation-time flag for requesting that the program
> be installed only if it can be offloaded to HW.
>
> Internally new command for ndo_xdp is added, this way we avoid
> putting checks into drivers since they all return -EINVAL on
> an unknown command.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

Acked-by: Daniel Borkmann <daniel@iogearbox.net>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 7/8] xdp: add reporting of offload mode
  2017-06-16 23:57 ` [RFC net-next 7/8] xdp: add reporting of offload mode Jakub Kicinski
@ 2017-06-19 23:40   ` Daniel Borkmann
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Borkmann @ 2017-06-19 23:40 UTC (permalink / raw)
  To: Jakub Kicinski, netdev; +Cc: davem, kafai, netoptimizer, oss-drivers

On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
> Extend the XDP_ATTACHED_* values to include offloaded mode.
> Let drivers report whether program is installed in the driver
> or the HW by changing the prog_attached field from bool to
> u8 (type of the netlink attribute).
>
> Exploit the fact that the value of XDP_ATTACHED_DRV is 1,
> therefore since all drivers currently assign the mode with
> double negation:
>         mode = !!xdp_prog;
> no drivers have to be modified.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

Acked-by: Daniel Borkmann <daniel@iogearbox.net>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 6/8] nfp: bpf: add support for XDP_FLAGS_HW_MODE
  2017-06-16 23:57 ` [RFC net-next 6/8] nfp: bpf: add support for XDP_FLAGS_HW_MODE Jakub Kicinski
@ 2017-06-19 23:50   ` Daniel Borkmann
  2017-06-20  0:01     ` Jakub Kicinski
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Borkmann @ 2017-06-19 23:50 UTC (permalink / raw)
  To: Jakub Kicinski, netdev; +Cc: davem, kafai, netoptimizer, oss-drivers

On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
> Respect the XDP_FLAGS_HW_MODE.  When it's set install the program
> on the NIC and skip enabling XDP in the driver.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> ---
>   drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 10 +++++++---
>   1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> index 68648e312129..c5903b6e58c5 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> @@ -3310,19 +3310,22 @@ static int
>   nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog, u32 flags,
>   		  struct netlink_ext_ack *extack)
>   {
> -	struct bpf_prog *offload_prog;
> +	struct bpf_prog *drv_prog, *offload_prog;
>   	int err;
>
>   	if (nn->xdp_prog && (flags ^ nn->xdp_flags) & XDP_FLAGS_MODES)
>   		return -EBUSY;
>
> +	drv_prog     = flags & XDP_FLAGS_HW_MODE  ? NULL : prog;
>   	offload_prog = flags & XDP_FLAGS_DRV_MODE ? NULL : prog;

Can you make this assumption here? If dev_change_xdp_fd() is called
without XDP_FLAGS_HW_MODE or XDP_FLAGS_DRV_MODE flags, then we set prog
to both, drv_prog and offload_prog. Is this expected?

Maybe in nfp_net_xdp_setup() check for !hweight32(xdp_flags & XDP_FLAGS_MODES)
and then set flags |= XDP_FLAGS_DRV_MODE before both assignments?

> -	err = nfp_net_xdp_setup_drv(nn, prog, extack);
> +	err = nfp_net_xdp_setup_drv(nn, drv_prog, extack);
>   	if (err)
>   		return err;
>
> -	nfp_app_xdp_offload(nn->app, nn, offload_prog);
> +	err = nfp_app_xdp_offload(nn->app, nn, offload_prog);
> +	if (err && flags & XDP_FLAGS_HW_MODE)
> +		return err;
>
>   	if (nn->xdp_prog)
>   		bpf_prog_put(nn->xdp_prog);
> @@ -3338,6 +3341,7 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_xdp *xdp)
>
>   	switch (xdp->command) {
>   	case XDP_SETUP_PROG:
> +	case XDP_SETUP_PROG_HW:
>   		return nfp_net_xdp_setup(nn, xdp->prog, xdp->flags,
>   					 xdp->extack);
>   	case XDP_QUERY_PROG:
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 6/8] nfp: bpf: add support for XDP_FLAGS_HW_MODE
  2017-06-19 23:50   ` Daniel Borkmann
@ 2017-06-20  0:01     ` Jakub Kicinski
  2017-06-20  0:09       ` Daniel Borkmann
  0 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2017-06-20  0:01 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: netdev, davem, kafai, brouer, oss-drivers

On Tue, 20 Jun 2017 01:50:17 +0200, Daniel Borkmann wrote:
> On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
> > Respect the XDP_FLAGS_HW_MODE.  When it's set install the program
> > on the NIC and skip enabling XDP in the driver.
> >
> > Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> > ---
> >   drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 10 +++++++---
> >   1 file changed, 7 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> > index 68648e312129..c5903b6e58c5 100644
> > --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> > +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> > @@ -3310,19 +3310,22 @@ static int
> >   nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog, u32 flags,
> >   		  struct netlink_ext_ack *extack)
> >   {
> > -	struct bpf_prog *offload_prog;
> > +	struct bpf_prog *drv_prog, *offload_prog;
> >   	int err;
> >
> >   	if (nn->xdp_prog && (flags ^ nn->xdp_flags) & XDP_FLAGS_MODES)
> >   		return -EBUSY;
> >
> > +	drv_prog     = flags & XDP_FLAGS_HW_MODE  ? NULL : prog;
> >   	offload_prog = flags & XDP_FLAGS_DRV_MODE ? NULL : prog;  
> 
> Can you make this assumption here? If dev_change_xdp_fd() is called
> without XDP_FLAGS_HW_MODE or XDP_FLAGS_DRV_MODE flags, then we set prog
> to both, drv_prog and offload_prog. Is this expected?
> 
> Maybe in nfp_net_xdp_setup() check for !hweight32(xdp_flags & XDP_FLAGS_MODES)
> and then set flags |= XDP_FLAGS_DRV_MODE before both assignments?

I thought we did want both.  In case the program is loaded to both the
HW/FW will mark the packets with BPF bit in the descriptor so that they
are not processed twice.  But the driver path will be configured for
running bpf and when user replaces the program with one which cannot be
offloaded the driver will not have to reconfigure itself.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC net-next 6/8] nfp: bpf: add support for XDP_FLAGS_HW_MODE
  2017-06-20  0:01     ` Jakub Kicinski
@ 2017-06-20  0:09       ` Daniel Borkmann
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Borkmann @ 2017-06-20  0:09 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev, davem, kafai, brouer, oss-drivers

On 06/20/2017 02:01 AM, Jakub Kicinski wrote:
> On Tue, 20 Jun 2017 01:50:17 +0200, Daniel Borkmann wrote:
>> On 06/17/2017 01:57 AM, Jakub Kicinski wrote:
>>> Respect the XDP_FLAGS_HW_MODE.  When it's set install the program
>>> on the NIC and skip enabling XDP in the driver.
>>>
>>> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
>>> ---
>>>    drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 10 +++++++---
>>>    1 file changed, 7 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
>>> index 68648e312129..c5903b6e58c5 100644
>>> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
>>> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
>>> @@ -3310,19 +3310,22 @@ static int
>>>    nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog, u32 flags,
>>>    		  struct netlink_ext_ack *extack)
>>>    {
>>> -	struct bpf_prog *offload_prog;
>>> +	struct bpf_prog *drv_prog, *offload_prog;
>>>    	int err;
>>>
>>>    	if (nn->xdp_prog && (flags ^ nn->xdp_flags) & XDP_FLAGS_MODES)
>>>    		return -EBUSY;
>>>
>>> +	drv_prog     = flags & XDP_FLAGS_HW_MODE  ? NULL : prog;
>>>    	offload_prog = flags & XDP_FLAGS_DRV_MODE ? NULL : prog;
>>
>> Can you make this assumption here? If dev_change_xdp_fd() is called
>> without XDP_FLAGS_HW_MODE or XDP_FLAGS_DRV_MODE flags, then we set prog
>> to both, drv_prog and offload_prog. Is this expected?
>>
>> Maybe in nfp_net_xdp_setup() check for !hweight32(xdp_flags & XDP_FLAGS_MODES)
>> and then set flags |= XDP_FLAGS_DRV_MODE before both assignments?
>
> I thought we did want both.  In case the program is loaded to both the
> HW/FW will mark the packets with BPF bit in the descriptor so that they
> are not processed twice.  But the driver path will be configured for
> running bpf and when user replaces the program with one which cannot be
> offloaded the driver will not have to reconfigure itself.

Okay, that's a good point ... so that you can just use xchg() later on.
Probably worth explaining this rationale in a short comment.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2017-06-20  0:09 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-16 23:57 [RFC net-next 0/8] xdp: offload mode Jakub Kicinski
2017-06-16 23:57 ` [RFC net-next 1/8] xdp: pass XDP flags into install handlers Jakub Kicinski
2017-06-19 23:38   ` Daniel Borkmann
2017-06-16 23:57 ` [RFC net-next 2/8] xdp: add HW offload mode flag for installing programs Jakub Kicinski
2017-06-19 22:55   ` Daniel Borkmann
2017-06-19 23:24     ` Jakub Kicinski
2017-06-19 23:36       ` Daniel Borkmann
2017-06-19 23:39   ` Daniel Borkmann
2017-06-16 23:57 ` [RFC net-next 3/8] nfp: xdp: move driver XDP setup into a separate function Jakub Kicinski
2017-06-16 23:57 ` [RFC net-next 4/8] nfp: bpf: don't offload XDP programs in DRV_MODE Jakub Kicinski
2017-06-16 23:57 ` [RFC net-next 5/8] nfp: bpf: take a reference on offloaded programs Jakub Kicinski
2017-06-19 23:23   ` Daniel Borkmann
2017-06-19 23:34     ` Jakub Kicinski
2017-06-16 23:57 ` [RFC net-next 6/8] nfp: bpf: add support for XDP_FLAGS_HW_MODE Jakub Kicinski
2017-06-19 23:50   ` Daniel Borkmann
2017-06-20  0:01     ` Jakub Kicinski
2017-06-20  0:09       ` Daniel Borkmann
2017-06-16 23:57 ` [RFC net-next 7/8] xdp: add reporting of offload mode Jakub Kicinski
2017-06-19 23:40   ` Daniel Borkmann
2017-06-16 23:57 ` [RFC net-next 8/8] nfp: xdp: report if program is offloaded Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).