Netdev List
 help / color / mirror / Atom feed
* [RESEND PATCH 0/5] net: Use FIELD_SIZEOF directly instead of reimplementing its function
From: zhong jiang @ 2018-09-19 11:32 UTC (permalink / raw)
  To: davem
  Cc: ubraun, jwi, jhs, xiyou.wangcong, Ariel.Elior, everest-linux-l2,
	grygorii.strashko, netdev, linux-kernel, borntraeger

The issue is detected with the help of Coccinelle.

zhong jiang (5):
  net: iucv: Use FIELD_SIZEOF directly instead of reimplementing its
    function
  net: sched: Use FIELD_SIZEOF directly instead of reimplementing its
    function
  net: core: Use FIELD_SIZEOF directly instead of reimplementing its
    function
  net: qede: Use FIELD_SIZEOF directly instead of reimplementing its
    function
  net: ti: Use FIELD_SIZEOF directly instead of reimplementing its
    function

 drivers/net/ethernet/qlogic/qede/qede.h |  2 +-
 drivers/net/ethernet/ti/cpsw.c          |  6 +++---
 net/core/flow_dissector.c               | 10 +++++-----
 net/iucv/af_iucv.c                      |  2 +-
 net/sched/cls_flower.c                  |  2 +-
 5 files changed, 11 insertions(+), 11 deletions(-)

-- 
1.7.12.4

^ permalink raw reply

* [PATCH net-next] net: sun: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-19 11:21 UTC (permalink / raw)
  To: davem, shannon.nelson, alexander.h.duyck, yanjun.zhu,
	jeffrey.t.kirsher, tklauser
  Cc: linux-kernel, netdev, YueHaibing

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, but the implementation in this
driver returns an 'int'.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/sun/ldmvsw.c         |  2 +-
 drivers/net/ethernet/sun/sunbmac.c        |  3 ++-
 drivers/net/ethernet/sun/sunqe.c          |  2 +-
 drivers/net/ethernet/sun/sunvnet.c        |  2 +-
 drivers/net/ethernet/sun/sunvnet_common.c | 14 ++++++++------
 drivers/net/ethernet/sun/sunvnet_common.h |  7 ++++---
 6 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c
index d42f47f..644e42c 100644
--- a/drivers/net/ethernet/sun/ldmvsw.c
+++ b/drivers/net/ethernet/sun/ldmvsw.c
@@ -113,7 +113,7 @@ static u16 vsw_select_queue(struct net_device *dev, struct sk_buff *skb,
 }
 
 /* Wrappers to common functions */
-static int vsw_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t vsw_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	return sunvnet_start_xmit_common(skb, dev, vsw_tx_port_find);
 }
diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c
index f047b27..720b7ac 100644
--- a/drivers/net/ethernet/sun/sunbmac.c
+++ b/drivers/net/ethernet/sun/sunbmac.c
@@ -950,7 +950,8 @@ static void bigmac_tx_timeout(struct net_device *dev)
 }
 
 /* Put a packet on the wire. */
-static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bigmac *bp = netdev_priv(dev);
 	int len, entry;
diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c
index 7fe0d5e..1468fa0 100644
--- a/drivers/net/ethernet/sun/sunqe.c
+++ b/drivers/net/ethernet/sun/sunqe.c
@@ -570,7 +570,7 @@ static void qe_tx_timeout(struct net_device *dev)
 }
 
 /* Get a packet queued to go onto the wire. */
-static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct sunqe *qep = netdev_priv(dev);
 	struct sunqe_buffers *qbufs = qep->buffers;
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 12539b3..5901728 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -247,7 +247,7 @@ static u16 vnet_select_queue(struct net_device *dev, struct sk_buff *skb,
 }
 
 /* Wrappers to common functions */
-static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	return sunvnet_start_xmit_common(skb, dev, vnet_tx_port_find);
 }
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index d8f4c3f..baa3088 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -1216,9 +1216,10 @@ static inline struct sk_buff *vnet_skb_shape(struct sk_buff *skb, int ncookies)
 	return skb;
 }
 
-static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb,
-				struct vnet_port *(*vnet_tx_port)
-				(struct sk_buff *, struct net_device *))
+static netdev_tx_t
+vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb,
+		     struct vnet_port *(*vnet_tx_port)
+		     (struct sk_buff *, struct net_device *))
 {
 	struct net_device *dev = VNET_PORT_TO_NET_DEVICE(port);
 	struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
@@ -1321,9 +1322,10 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb,
 	return NETDEV_TX_OK;
 }
 
-int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
-			      struct vnet_port *(*vnet_tx_port)
-			      (struct sk_buff *, struct net_device *))
+netdev_tx_t
+sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
+			  struct vnet_port *(*vnet_tx_port)
+			  (struct sk_buff *, struct net_device *))
 {
 	struct vnet_port *port = NULL;
 	struct vio_dring_state *dr;
diff --git a/drivers/net/ethernet/sun/sunvnet_common.h b/drivers/net/ethernet/sun/sunvnet_common.h
index 1ea0b01..2b808d2 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.h
+++ b/drivers/net/ethernet/sun/sunvnet_common.h
@@ -136,9 +136,10 @@ struct vnet {
 void sunvnet_set_rx_mode_common(struct net_device *dev, struct vnet *vp);
 int sunvnet_set_mac_addr_common(struct net_device *dev, void *p);
 void sunvnet_tx_timeout_common(struct net_device *dev);
-int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
-			   struct vnet_port *(*vnet_tx_port)
-			   (struct sk_buff *, struct net_device *));
+netdev_tx_t
+sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
+			  struct vnet_port *(*vnet_tx_port)
+			  (struct sk_buff *, struct net_device *));
 #ifdef CONFIG_NET_POLL_CONTROLLER
 void sunvnet_poll_controller_common(struct net_device *dev, struct vnet *vp);
 #endif
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH 1/5] net: iucv: Use FIELD_SIZEOF directly instead of reimplementing its function
From: Christian Borntraeger @ 2018-09-19 11:21 UTC (permalink / raw)
  To: zhong jiang, davem
  Cc: jhs, xiyou.wangcong, jiri, netdev, linux-kernel, Ursula Braun,
	Julian Wiedmann
In-Reply-To: <1537352781-48532-2-git-send-email-zhongjiang@huawei.com>

Can you please copy Ursula and Julian for iucv related patches?

On 09/19/2018 12:26 PM, zhong jiang wrote:
> FIELD_SIZEOF is defined as a macro to calculate the specified value. Therefore,
> We prefer to use the macro rather than calculating its value.
> 
> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
> ---
>  net/iucv/af_iucv.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
> index e2f16a0..5b68ee9 100644
> --- a/net/iucv/af_iucv.c
> +++ b/net/iucv/af_iucv.c
> @@ -48,7 +48,7 @@
>  static const u8 iprm_shutdown[8] =
>  	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
>  
> -#define TRGCLS_SIZE	(sizeof(((struct iucv_message *)0)->class))
> +#define TRGCLS_SIZE	FIELD_SIZEOF(struct iucv_message, class)
>  
>  #define __iucv_sock_wait(sk, condition, timeo, ret)			\
>  do {									\
> 

^ permalink raw reply

* Re: [PATCH 6/6] net: sun: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-19 11:20 UTC (permalink / raw)
  To: davem, shannon.nelson, alexander.h.duyck, yanjun.zhu,
	jeffrey.t.kirsher, tklauser
  Cc: linux-kernel, netdev
In-Reply-To: <20180919110702.10280-1-yuehaibing@huawei.com>

Sorry for wrongly title, will repost.

On 2018/9/19 19:07, YueHaibing wrote:
> The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
> which is a typedef for an enum type, but the implementation in this
> driver returns an 'int'.
> 
> Found by coccinelle.
> 
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
>  drivers/net/ethernet/sun/ldmvsw.c         |  2 +-
>  drivers/net/ethernet/sun/sunbmac.c        |  3 ++-
>  drivers/net/ethernet/sun/sunqe.c          |  2 +-
>  drivers/net/ethernet/sun/sunvnet.c        |  2 +-
>  drivers/net/ethernet/sun/sunvnet_common.c | 14 ++++++++------
>  drivers/net/ethernet/sun/sunvnet_common.h |  7 ++++---
>  6 files changed, 17 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c
> index d42f47f..644e42c 100644
> --- a/drivers/net/ethernet/sun/ldmvsw.c
> +++ b/drivers/net/ethernet/sun/ldmvsw.c
> @@ -113,7 +113,7 @@ static u16 vsw_select_queue(struct net_device *dev, struct sk_buff *skb,
>  }
>  
>  /* Wrappers to common functions */
> -static int vsw_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +static netdev_tx_t vsw_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	return sunvnet_start_xmit_common(skb, dev, vsw_tx_port_find);
>  }
> diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c
> index f047b27..720b7ac 100644
> --- a/drivers/net/ethernet/sun/sunbmac.c
> +++ b/drivers/net/ethernet/sun/sunbmac.c
> @@ -950,7 +950,8 @@ static void bigmac_tx_timeout(struct net_device *dev)
>  }
>  
>  /* Put a packet on the wire. */
> -static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +static netdev_tx_t
> +bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	struct bigmac *bp = netdev_priv(dev);
>  	int len, entry;
> diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c
> index 7fe0d5e..1468fa0 100644
> --- a/drivers/net/ethernet/sun/sunqe.c
> +++ b/drivers/net/ethernet/sun/sunqe.c
> @@ -570,7 +570,7 @@ static void qe_tx_timeout(struct net_device *dev)
>  }
>  
>  /* Get a packet queued to go onto the wire. */
> -static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +static netdev_tx_t qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	struct sunqe *qep = netdev_priv(dev);
>  	struct sunqe_buffers *qbufs = qep->buffers;
> diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
> index 12539b3..5901728 100644
> --- a/drivers/net/ethernet/sun/sunvnet.c
> +++ b/drivers/net/ethernet/sun/sunvnet.c
> @@ -247,7 +247,7 @@ static u16 vnet_select_queue(struct net_device *dev, struct sk_buff *skb,
>  }
>  
>  /* Wrappers to common functions */
> -static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +static netdev_tx_t vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>  	return sunvnet_start_xmit_common(skb, dev, vnet_tx_port_find);
>  }
> diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
> index d8f4c3f..baa3088 100644
> --- a/drivers/net/ethernet/sun/sunvnet_common.c
> +++ b/drivers/net/ethernet/sun/sunvnet_common.c
> @@ -1216,9 +1216,10 @@ static inline struct sk_buff *vnet_skb_shape(struct sk_buff *skb, int ncookies)
>  	return skb;
>  }
>  
> -static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb,
> -				struct vnet_port *(*vnet_tx_port)
> -				(struct sk_buff *, struct net_device *))
> +static netdev_tx_t
> +vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb,
> +		     struct vnet_port *(*vnet_tx_port)
> +		     (struct sk_buff *, struct net_device *))
>  {
>  	struct net_device *dev = VNET_PORT_TO_NET_DEVICE(port);
>  	struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
> @@ -1321,9 +1322,10 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb,
>  	return NETDEV_TX_OK;
>  }
>  
> -int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
> -			      struct vnet_port *(*vnet_tx_port)
> -			      (struct sk_buff *, struct net_device *))
> +netdev_tx_t
> +sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
> +			  struct vnet_port *(*vnet_tx_port)
> +			  (struct sk_buff *, struct net_device *))
>  {
>  	struct vnet_port *port = NULL;
>  	struct vio_dring_state *dr;
> diff --git a/drivers/net/ethernet/sun/sunvnet_common.h b/drivers/net/ethernet/sun/sunvnet_common.h
> index 1ea0b01..2b808d2 100644
> --- a/drivers/net/ethernet/sun/sunvnet_common.h
> +++ b/drivers/net/ethernet/sun/sunvnet_common.h
> @@ -136,9 +136,10 @@ struct vnet {
>  void sunvnet_set_rx_mode_common(struct net_device *dev, struct vnet *vp);
>  int sunvnet_set_mac_addr_common(struct net_device *dev, void *p);
>  void sunvnet_tx_timeout_common(struct net_device *dev);
> -int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
> -			   struct vnet_port *(*vnet_tx_port)
> -			   (struct sk_buff *, struct net_device *));
> +netdev_tx_t
> +sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
> +			  struct vnet_port *(*vnet_tx_port)
> +			  (struct sk_buff *, struct net_device *));
>  #ifdef CONFIG_NET_POLL_CONTROLLER
>  void sunvnet_poll_controller_common(struct net_device *dev, struct vnet *vp);
>  #endif
> 

^ permalink raw reply

* [PATCH 6/6] net: sun: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-19 11:07 UTC (permalink / raw)
  To: davem, shannon.nelson, alexander.h.duyck, yanjun.zhu,
	jeffrey.t.kirsher, tklauser
  Cc: linux-kernel, netdev, YueHaibing

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, but the implementation in this
driver returns an 'int'.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/sun/ldmvsw.c         |  2 +-
 drivers/net/ethernet/sun/sunbmac.c        |  3 ++-
 drivers/net/ethernet/sun/sunqe.c          |  2 +-
 drivers/net/ethernet/sun/sunvnet.c        |  2 +-
 drivers/net/ethernet/sun/sunvnet_common.c | 14 ++++++++------
 drivers/net/ethernet/sun/sunvnet_common.h |  7 ++++---
 6 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c
index d42f47f..644e42c 100644
--- a/drivers/net/ethernet/sun/ldmvsw.c
+++ b/drivers/net/ethernet/sun/ldmvsw.c
@@ -113,7 +113,7 @@ static u16 vsw_select_queue(struct net_device *dev, struct sk_buff *skb,
 }
 
 /* Wrappers to common functions */
-static int vsw_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t vsw_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	return sunvnet_start_xmit_common(skb, dev, vsw_tx_port_find);
 }
diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c
index f047b27..720b7ac 100644
--- a/drivers/net/ethernet/sun/sunbmac.c
+++ b/drivers/net/ethernet/sun/sunbmac.c
@@ -950,7 +950,8 @@ static void bigmac_tx_timeout(struct net_device *dev)
 }
 
 /* Put a packet on the wire. */
-static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bigmac *bp = netdev_priv(dev);
 	int len, entry;
diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c
index 7fe0d5e..1468fa0 100644
--- a/drivers/net/ethernet/sun/sunqe.c
+++ b/drivers/net/ethernet/sun/sunqe.c
@@ -570,7 +570,7 @@ static void qe_tx_timeout(struct net_device *dev)
 }
 
 /* Get a packet queued to go onto the wire. */
-static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct sunqe *qep = netdev_priv(dev);
 	struct sunqe_buffers *qbufs = qep->buffers;
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 12539b3..5901728 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -247,7 +247,7 @@ static u16 vnet_select_queue(struct net_device *dev, struct sk_buff *skb,
 }
 
 /* Wrappers to common functions */
-static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	return sunvnet_start_xmit_common(skb, dev, vnet_tx_port_find);
 }
diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c
index d8f4c3f..baa3088 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.c
+++ b/drivers/net/ethernet/sun/sunvnet_common.c
@@ -1216,9 +1216,10 @@ static inline struct sk_buff *vnet_skb_shape(struct sk_buff *skb, int ncookies)
 	return skb;
 }
 
-static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb,
-				struct vnet_port *(*vnet_tx_port)
-				(struct sk_buff *, struct net_device *))
+static netdev_tx_t
+vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb,
+		     struct vnet_port *(*vnet_tx_port)
+		     (struct sk_buff *, struct net_device *))
 {
 	struct net_device *dev = VNET_PORT_TO_NET_DEVICE(port);
 	struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
@@ -1321,9 +1322,10 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb,
 	return NETDEV_TX_OK;
 }
 
-int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
-			      struct vnet_port *(*vnet_tx_port)
-			      (struct sk_buff *, struct net_device *))
+netdev_tx_t
+sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
+			  struct vnet_port *(*vnet_tx_port)
+			  (struct sk_buff *, struct net_device *))
 {
 	struct vnet_port *port = NULL;
 	struct vio_dring_state *dr;
diff --git a/drivers/net/ethernet/sun/sunvnet_common.h b/drivers/net/ethernet/sun/sunvnet_common.h
index 1ea0b01..2b808d2 100644
--- a/drivers/net/ethernet/sun/sunvnet_common.h
+++ b/drivers/net/ethernet/sun/sunvnet_common.h
@@ -136,9 +136,10 @@ struct vnet {
 void sunvnet_set_rx_mode_common(struct net_device *dev, struct vnet *vp);
 int sunvnet_set_mac_addr_common(struct net_device *dev, void *p);
 void sunvnet_tx_timeout_common(struct net_device *dev);
-int sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
-			   struct vnet_port *(*vnet_tx_port)
-			   (struct sk_buff *, struct net_device *));
+netdev_tx_t
+sunvnet_start_xmit_common(struct sk_buff *skb, struct net_device *dev,
+			  struct vnet_port *(*vnet_tx_port)
+			  (struct sk_buff *, struct net_device *));
 #ifdef CONFIG_NET_POLL_CONTROLLER
 void sunvnet_poll_controller_common(struct net_device *dev, struct vnet *vp);
 #endif
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next] net: amd: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-19 10:50 UTC (permalink / raw)
  To: davem, linux, thomas.lendacky, keescook, allen.lkml
  Cc: linux-kernel, netdev, linux-arm-kernel, YueHaibing

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/amd/am79c961a.c     | 2 +-
 drivers/net/ethernet/amd/atarilance.c    | 6 ++++--
 drivers/net/ethernet/amd/declance.c      | 2 +-
 drivers/net/ethernet/amd/sun3lance.c     | 6 ++++--
 drivers/net/ethernet/amd/sunlance.c      | 2 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 4 ++--
 6 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/amd/am79c961a.c b/drivers/net/ethernet/amd/am79c961a.c
index 01d132c..265039c 100644
--- a/drivers/net/ethernet/amd/am79c961a.c
+++ b/drivers/net/ethernet/amd/am79c961a.c
@@ -440,7 +440,7 @@ static void am79c961_timeout(struct net_device *dev)
 /*
  * Transmit a packet
  */
-static int
+static netdev_tx_t
 am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
 {
 	struct dev_priv *priv = netdev_priv(dev);
diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c
index c5b8126..d3d44e0 100644
--- a/drivers/net/ethernet/amd/atarilance.c
+++ b/drivers/net/ethernet/amd/atarilance.c
@@ -339,7 +339,8 @@ static unsigned long lance_probe1( struct net_device *dev, struct lance_addr
                                    *init_rec );
 static int lance_open( struct net_device *dev );
 static void lance_init_ring( struct net_device *dev );
-static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
+static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev);
 static irqreturn_t lance_interrupt( int irq, void *dev_id );
 static int lance_rx( struct net_device *dev );
 static int lance_close( struct net_device *dev );
@@ -769,7 +770,8 @@ static void lance_tx_timeout (struct net_device *dev)
 
 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 
-static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
+static netdev_tx_t
+lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
 	struct lance_ioreg	 *IO = lp->iobase;
diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c
index 116997a..29ebbf5 100644
--- a/drivers/net/ethernet/amd/declance.c
+++ b/drivers/net/ethernet/amd/declance.c
@@ -894,7 +894,7 @@ static void lance_tx_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
 	volatile struct lance_regs *ll = lp->ll;
diff --git a/drivers/net/ethernet/amd/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c
index 77b1db2..da7e3d4 100644
--- a/drivers/net/ethernet/amd/sun3lance.c
+++ b/drivers/net/ethernet/amd/sun3lance.c
@@ -236,7 +236,8 @@ struct lance_private {
 static int lance_probe( struct net_device *dev);
 static int lance_open( struct net_device *dev );
 static void lance_init_ring( struct net_device *dev );
-static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
+static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev);
 static irqreturn_t lance_interrupt( int irq, void *dev_id);
 static int lance_rx( struct net_device *dev );
 static int lance_close( struct net_device *dev );
@@ -511,7 +512,8 @@ static void lance_init_ring( struct net_device *dev )
 }
 
 
-static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
+static netdev_tx_t
+lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
 	int entry, len;
diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c
index cdd7a61..b4fc0ed 100644
--- a/drivers/net/ethernet/amd/sunlance.c
+++ b/drivers/net/ethernet/amd/sunlance.c
@@ -1106,7 +1106,7 @@ static void lance_tx_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
 	int entry, skblen, len;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 24f1053..d96a84a 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -2009,7 +2009,7 @@ static int xgbe_close(struct net_device *netdev)
 	return 0;
 }
 
-static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct xgbe_prv_data *pdata = netdev_priv(netdev);
 	struct xgbe_hw_if *hw_if = &pdata->hw_if;
@@ -2018,7 +2018,7 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
 	struct xgbe_ring *ring;
 	struct xgbe_packet_data *packet;
 	struct netdev_queue *txq;
-	int ret;
+	netdev_tx_t ret;
 
 	DBGPR("-->xgbe_xmit: skb->len = %d\n", skb->len);
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next] net: broadcom: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-19 10:45 UTC (permalink / raw)
  To: davem, f.fainelli, bcm-kernel-feedback-list, jonas.gorski, andrew,
	himanshujha199640, keescook
  Cc: linux-kernel, netdev, linux-arm-kernel, YueHaibing

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/broadcom/bcm63xx_enet.c | 5 +++--
 drivers/net/ethernet/broadcom/sb1250-mac.c   | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index 02e7dfc..6bae973 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -568,12 +568,13 @@ static irqreturn_t bcm_enet_isr_dma(int irq, void *dev_id)
 /*
  * tx request callback
  */
-static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bcm_enet_priv *priv;
 	struct bcm_enet_desc *desc;
 	u32 len_stat;
-	int ret;
+	netdev_tx_t ret;
 
 	priv = netdev_priv(dev);
 
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c
index c44cff5..5db9f41 100644
--- a/drivers/net/ethernet/broadcom/sb1250-mac.c
+++ b/drivers/net/ethernet/broadcom/sb1250-mac.c
@@ -299,7 +299,7 @@ static enum sbmac_state sbmac_set_channel_state(struct sbmac_softc *,
 static void sbmac_promiscuous_mode(struct sbmac_softc *sc, int onoff);
 static uint64_t sbmac_addr2reg(unsigned char *ptr);
 static irqreturn_t sbmac_intr(int irq, void *dev_instance);
-static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t sbmac_start_tx(struct sk_buff *skb, struct net_device *dev);
 static void sbmac_setmulti(struct sbmac_softc *sc);
 static int sbmac_init(struct platform_device *pldev, long long base);
 static int sbmac_set_speed(struct sbmac_softc *s, enum sbmac_speed speed);
@@ -2028,7 +2028,7 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance)
  *  Return value:
  *  	   nothing
  ********************************************************************* */
-static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct sbmac_softc *sc = netdev_priv(dev);
 	unsigned long flags;
-- 
1.8.3.1

^ permalink raw reply related

* Re: Project Financing
From: Gabriel Walker @ 2018-09-19  5:05 UTC (permalink / raw)


Thank you for your time,

We are looking for clients in your country with good business or project that requires financing to execute.

Do get back to me if you are interested in this or you know anybody who has good business ideas but lack the necessary capital to fund his projects so we can establish working relationship.

Sincerely,
 
John Hanan, MBA, CFA
General Investment Consultant 

^ permalink raw reply

* Re: [PATCH net-next] net: toshiba: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-19 10:35 UTC (permalink / raw)
  To: davem, michal.simek, anirudh, John.Linn
  Cc: linux-kernel, netdev, linux-arm-kernel
In-Reply-To: <20180919103240.27708-1-yuehaibing@huawei.com>

sorry, this is a duplicated patch,Pls ignore it.

On 2018/9/19 18:32, YueHaibing wrote:
> The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
> which is a typedef for an enum type, so make sure the implementation in
> this driver has returns 'netdev_tx_t' value, and change the function
> return type to netdev_tx_t.
> 
> Found by coccinelle.
> 
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
>  drivers/net/ethernet/toshiba/ps3_gelic_net.c | 4 ++--
>  drivers/net/ethernet/toshiba/ps3_gelic_net.h | 2 +-
>  drivers/net/ethernet/toshiba/spider_net.c    | 4 ++--
>  drivers/net/ethernet/toshiba/tc35815.c       | 6 ++++--
>  4 files changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
> index 88d74ae..75237c8 100644
> --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c
> +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
> @@ -845,9 +845,9 @@ static int gelic_card_kick_txdma(struct gelic_card *card,
>   * @skb: packet to send out
>   * @netdev: interface device structure
>   *
> - * returns 0 on success, <0 on failure
> + * returns NETDEV_TX_OK on success, NETDEV_TX_BUSY on failure
>   */
> -int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
> +netdev_tx_t gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
>  {
>  	struct gelic_card *card = netdev_card(netdev);
>  	struct gelic_descr *descr;
> diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.h b/drivers/net/ethernet/toshiba/ps3_gelic_net.h
> index 003d045..fbbf9b5 100644
> --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.h
> +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.h
> @@ -370,7 +370,7 @@ static inline void udbg_shutdown_ps3gelic(void) {}
>  void gelic_card_down(struct gelic_card *card);
>  int gelic_net_open(struct net_device *netdev);
>  int gelic_net_stop(struct net_device *netdev);
> -int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
> +netdev_tx_t gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
>  void gelic_net_set_multi(struct net_device *netdev);
>  void gelic_net_tx_timeout(struct net_device *netdev);
>  int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card);
> diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c
> index d925b82..2341726 100644
> --- a/drivers/net/ethernet/toshiba/spider_net.c
> +++ b/drivers/net/ethernet/toshiba/spider_net.c
> @@ -880,9 +880,9 @@
>   * @skb: packet to send out
>   * @netdev: interface device structure
>   *
> - * returns 0 on success, !0 on failure
> + * returns NETDEV_TX_OK on success, NETDEV_TX_BUSY on failure
>   */
> -static int
> +static netdev_tx_t
>  spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
>  {
>  	int cnt;
> diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
> index 7163a8d..6a71c2c 100644
> --- a/drivers/net/ethernet/toshiba/tc35815.c
> +++ b/drivers/net/ethernet/toshiba/tc35815.c
> @@ -474,7 +474,8 @@ static void free_rxbuf_skb(struct pci_dev *hwdev, struct sk_buff *skb, dma_addr_
>  /* Index to functions, as function prototypes. */
>  
>  static int	tc35815_open(struct net_device *dev);
> -static int	tc35815_send_packet(struct sk_buff *skb, struct net_device *dev);
> +static netdev_tx_t	tc35815_send_packet(struct sk_buff *skb,
> +					    struct net_device *dev);
>  static irqreturn_t	tc35815_interrupt(int irq, void *dev_id);
>  static int	tc35815_rx(struct net_device *dev, int limit);
>  static int	tc35815_poll(struct napi_struct *napi, int budget);
> @@ -1248,7 +1249,8 @@ static void tc35815_tx_timeout(struct net_device *dev)
>   * invariant will hold if you make sure that the netif_*_queue()
>   * calls are done at the proper times.
>   */
> -static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
> +static netdev_tx_t
> +tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
>  {
>  	struct tc35815_local *lp = netdev_priv(dev);
>  	struct TxFD *txfd;
> 

^ permalink raw reply

* [PATCH net-next] net: xilinx: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-19 10:32 UTC (permalink / raw)
  To: davem, michal.simek, anirudh, John.Linn
  Cc: linux-kernel, netdev, linux-arm-kernel, YueHaibing
In-Reply-To: <20180919103240.27708-1-yuehaibing@huawei.com>

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/xilinx/ll_temac_main.c       | 3 ++-
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 3 ++-
 drivers/net/ethernet/xilinx/xilinx_emaclite.c     | 9 +++++----
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 60abc92..2241f98 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -674,7 +674,8 @@ static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag)
 	return 0;
 }
 
-static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t
+temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
 	struct temac_local *lp = netdev_priv(ndev);
 	struct cdmac_bd *cur_p;
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index f24f48f..12a1460 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -653,7 +653,8 @@ static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
  * start the transmission. Additionally if checksum offloading is supported,
  * it populates AXI Stream Control fields with appropriate values.
  */
-static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t
+axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
 	u32 ii;
 	u32 num_frag;
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 46d3092..639e3e9 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -1019,9 +1019,10 @@ static int xemaclite_close(struct net_device *dev)
  * deferred and the Tx queue is stopped so that the deferred socket buffer can
  * be transmitted when the Emaclite device is free to transmit data.
  *
- * Return:	0, always.
+ * Return:	NETDEV_TX_OK, always.
  */
-static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
+static netdev_tx_t
+xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
 	struct sk_buff *new_skb;
@@ -1043,7 +1044,7 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
 		/* Take the time stamp now, since we can't do this in an ISR. */
 		skb_tx_timestamp(new_skb);
 		spin_unlock_irqrestore(&lp->reset_lock, flags);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	spin_unlock_irqrestore(&lp->reset_lock, flags);
 
@@ -1052,7 +1053,7 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
 	dev->stats.tx_bytes += len;
 	dev_consume_skb_any(new_skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /**
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next] net: toshiba: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-19 10:32 UTC (permalink / raw)
  To: davem, michal.simek, anirudh, John.Linn
  Cc: linux-kernel, netdev, linux-arm-kernel, YueHaibing

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/toshiba/ps3_gelic_net.c | 4 ++--
 drivers/net/ethernet/toshiba/ps3_gelic_net.h | 2 +-
 drivers/net/ethernet/toshiba/spider_net.c    | 4 ++--
 drivers/net/ethernet/toshiba/tc35815.c       | 6 ++++--
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
index 88d74ae..75237c8 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
@@ -845,9 +845,9 @@ static int gelic_card_kick_txdma(struct gelic_card *card,
  * @skb: packet to send out
  * @netdev: interface device structure
  *
- * returns 0 on success, <0 on failure
+ * returns NETDEV_TX_OK on success, NETDEV_TX_BUSY on failure
  */
-int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+netdev_tx_t gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct gelic_card *card = netdev_card(netdev);
 	struct gelic_descr *descr;
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.h b/drivers/net/ethernet/toshiba/ps3_gelic_net.h
index 003d045..fbbf9b5 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_net.h
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.h
@@ -370,7 +370,7 @@ static inline void udbg_shutdown_ps3gelic(void) {}
 void gelic_card_down(struct gelic_card *card);
 int gelic_net_open(struct net_device *netdev);
 int gelic_net_stop(struct net_device *netdev);
-int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
+netdev_tx_t gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
 void gelic_net_set_multi(struct net_device *netdev);
 void gelic_net_tx_timeout(struct net_device *netdev);
 int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card);
diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c
index d925b82..2341726 100644
--- a/drivers/net/ethernet/toshiba/spider_net.c
+++ b/drivers/net/ethernet/toshiba/spider_net.c
@@ -880,9 +880,9 @@
  * @skb: packet to send out
  * @netdev: interface device structure
  *
- * returns 0 on success, !0 on failure
+ * returns NETDEV_TX_OK on success, NETDEV_TX_BUSY on failure
  */
-static int
+static netdev_tx_t
 spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	int cnt;
diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
index 7163a8d..6a71c2c 100644
--- a/drivers/net/ethernet/toshiba/tc35815.c
+++ b/drivers/net/ethernet/toshiba/tc35815.c
@@ -474,7 +474,8 @@ static void free_rxbuf_skb(struct pci_dev *hwdev, struct sk_buff *skb, dma_addr_
 /* Index to functions, as function prototypes. */
 
 static int	tc35815_open(struct net_device *dev);
-static int	tc35815_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t	tc35815_send_packet(struct sk_buff *skb,
+					    struct net_device *dev);
 static irqreturn_t	tc35815_interrupt(int irq, void *dev_id);
 static int	tc35815_rx(struct net_device *dev, int limit);
 static int	tc35815_poll(struct napi_struct *napi, int budget);
@@ -1248,7 +1249,8 @@ static void tc35815_tx_timeout(struct net_device *dev)
  * invariant will hold if you make sure that the netif_*_queue()
  * calls are done at the proper times.
  */
-static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	struct tc35815_local *lp = netdev_priv(dev);
 	struct TxFD *txfd;
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH] net: iucv: Use FIELD_SIZEOF directly instead of reimplementing its function
From: zhong jiang @ 2018-09-19 10:31 UTC (permalink / raw)
  To: davem; +Cc: ubraun, jwi, netdev, linux-kernel
In-Reply-To: <1537350733-44276-1-git-send-email-zhongjiang@huawei.com>

On 2018/9/19 17:52, zhong jiang wrote:
> FIELD_SIZEOF is defined as a macro to calculate the specified vaule. Therefore,
> We prefer to use the macro rather than calculating its vaule.
s/vaule/value  .   will resend .

Thanks,
zhong jiang
> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
> ---
>  net/iucv/af_iucv.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
> index e2f16a0..5b68ee9 100644
> --- a/net/iucv/af_iucv.c
> +++ b/net/iucv/af_iucv.c
> @@ -48,7 +48,7 @@
>  static const u8 iprm_shutdown[8] =
>  	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
>  
> -#define TRGCLS_SIZE	(sizeof(((struct iucv_message *)0)->class))
> +#define TRGCLS_SIZE	FIELD_SIZEOF(struct iucv_message, class)
>  
>  #define __iucv_sock_wait(sk, condition, timeo, ret)			\
>  do {									\

^ permalink raw reply

* Re: [PATCH] net: sched: Use FIELD_SIZEOF directly instead of reimplementing its function
From: zhong jiang @ 2018-09-19 10:30 UTC (permalink / raw)
  To: davem; +Cc: jhs, xiyou.wangcong, jiri, netdev, linux-kernel
In-Reply-To: <1537351001-44480-1-git-send-email-zhongjiang@huawei.com>

On 2018/9/19 17:56, zhong jiang wrote:
> FIELD_SIZEOF is defined as a macro to calculate the specified vaule. Therefore,
> We prefer to use the macro rather than calculating its vaule.
s/vaule/value.    will resend. sorry.

Thanks
zhong jiang
> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
> ---
>  net/sched/cls_flower.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
> index 4b8dd37..9aada2d 100644
> --- a/net/sched/cls_flower.c
> +++ b/net/sched/cls_flower.c
> @@ -993,7 +993,7 @@ static int fl_init_mask_hashtable(struct fl_flow_mask *mask)
>  }
>  
>  #define FL_KEY_MEMBER_OFFSET(member) offsetof(struct fl_flow_key, member)
> -#define FL_KEY_MEMBER_SIZE(member) (sizeof(((struct fl_flow_key *) 0)->member))
> +#define FL_KEY_MEMBER_SIZE(member) FIELD_SIZEOF(struct fl_flow_key, member)
>  
>  #define FL_KEY_IS_MASKED(mask, member)						\
>  	memchr_inv(((char *)mask) + FL_KEY_MEMBER_OFFSET(member),		\

^ permalink raw reply

* [PATCH 5/5] net: ti: Use FIELD_SIZEOF directly instead of reimplementing its function
From: zhong jiang @ 2018-09-19 10:26 UTC (permalink / raw)
  To: davem; +Cc: jhs, xiyou.wangcong, jiri, netdev, linux-kernel
In-Reply-To: <1537352781-48532-1-git-send-email-zhongjiang@huawei.com>

FIELD_SIZEOF is defined as a macro to calculate the specified value. Therefore,
We prefer to use the macro rather than calculating its value.

Signed-off-by: zhong jiang <zhongjiang@huawei.com>
---
 drivers/net/ethernet/ti/cpsw.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 832bce0..16dcbf3 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -484,13 +484,13 @@ enum {
 };
 
 #define CPSW_STAT(m)		CPSW_STATS,				\
-				sizeof(((struct cpsw_hw_stats *)0)->m), \
+				FIELD_SIZEOF(struct cpsw_hw_stats, m), \
 				offsetof(struct cpsw_hw_stats, m)
 #define CPDMA_RX_STAT(m)	CPDMA_RX_STATS,				   \
-				sizeof(((struct cpdma_chan_stats *)0)->m), \
+				FIELD_SIZEOF(struct cpdma_chan_stats, m), \
 				offsetof(struct cpdma_chan_stats, m)
 #define CPDMA_TX_STAT(m)	CPDMA_TX_STATS,				   \
-				sizeof(((struct cpdma_chan_stats *)0)->m), \
+				FIELD_SIZEOF(struct cpdma_chan_stats, m), \
 				offsetof(struct cpdma_chan_stats, m)
 
 static const struct cpsw_stats cpsw_gstrings_stats[] = {
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 4/5] net: qede: Use FIELD_SIZEOF directly instead of reimplementing its function
From: zhong jiang @ 2018-09-19 10:26 UTC (permalink / raw)
  To: davem; +Cc: jhs, xiyou.wangcong, jiri, netdev, linux-kernel
In-Reply-To: <1537352781-48532-1-git-send-email-zhongjiang@huawei.com>

FIELD_SIZEOF is defined as a macro to calculate the specified value. Therefore,
We prefer to use the macro rather than calculating its value.

Signed-off-by: zhong jiang <zhongjiang@huawei.com>
---
 drivers/net/ethernet/qlogic/qede/qede.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index 6a4d266..c73839c 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -440,7 +440,7 @@ struct qede_fastpath {
 	struct qede_tx_queue	*txq;
 	struct qede_tx_queue	*xdp_tx;
 
-#define VEC_NAME_SIZE	(sizeof(((struct net_device *)0)->name) + 8)
+	#define VEC_NAME_SIZE  (FIELD_SIZEOF(struct net_device, name) + 8)
 	char	name[VEC_NAME_SIZE];
 };
 
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 3/5] net: core: Use FIELD_SIZEOF directly instead of reimplementing its function
From: zhong jiang @ 2018-09-19 10:26 UTC (permalink / raw)
  To: davem; +Cc: jhs, xiyou.wangcong, jiri, netdev, linux-kernel
In-Reply-To: <1537352781-48532-1-git-send-email-zhongjiang@huawei.com>

FIELD_SIZEOF is defined as a macro to calculate the specified value. Therefore,
We prefer to use the macro rather than calculating its value.

Signed-off-by: zhong jiang <zhongjiang@huawei.com>
---
 net/core/flow_dissector.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 5c5dd74..aeac884 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -423,8 +423,8 @@ __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
 	offset += sizeof(struct gre_base_hdr);
 
 	if (hdr->flags & GRE_CSUM)
-		offset += sizeof(((struct gre_full_hdr *) 0)->csum) +
-			  sizeof(((struct gre_full_hdr *) 0)->reserved1);
+		offset += FIELD_SIZEOF(struct gre_full_hdr, csum) +
+			  FIELD_SIZEOF(struct gre_full_hdr, reserved1);
 
 	if (hdr->flags & GRE_KEY) {
 		const __be32 *keyid;
@@ -446,11 +446,11 @@ __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
 			else
 				key_keyid->keyid = *keyid & GRE_PPTP_KEY_MASK;
 		}
-		offset += sizeof(((struct gre_full_hdr *) 0)->key);
+		offset += FIELD_SIZEOF(struct gre_full_hdr, key);
 	}
 
 	if (hdr->flags & GRE_SEQ)
-		offset += sizeof(((struct pptp_gre_header *) 0)->seq);
+		offset += FIELD_SIZEOF(struct pptp_gre_header, seq);
 
 	if (gre_ver == 0) {
 		if (*p_proto == htons(ETH_P_TEB)) {
@@ -477,7 +477,7 @@ __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
 		u8 *ppp_hdr;
 
 		if (hdr->flags & GRE_ACK)
-			offset += sizeof(((struct pptp_gre_header *) 0)->ack);
+			offset += FIELD_SIZEOF(struct pptp_gre_header, ack);
 
 		ppp_hdr = __skb_header_pointer(skb, *p_nhoff + offset,
 					       sizeof(_ppp_hdr),
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 2/5] net: sched: Use FIELD_SIZEOF directly instead of reimplementing its function
From: zhong jiang @ 2018-09-19 10:26 UTC (permalink / raw)
  To: davem; +Cc: jhs, xiyou.wangcong, jiri, netdev, linux-kernel
In-Reply-To: <1537352781-48532-1-git-send-email-zhongjiang@huawei.com>

FIELD_SIZEOF is defined as a macro to calculate the specified value. Therefore,
We prefer to use the macro rather than calculating its value.

Signed-off-by: zhong jiang <zhongjiang@huawei.com>
---
 net/sched/cls_flower.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 4b8dd37..9aada2d 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -993,7 +993,7 @@ static int fl_init_mask_hashtable(struct fl_flow_mask *mask)
 }
 
 #define FL_KEY_MEMBER_OFFSET(member) offsetof(struct fl_flow_key, member)
-#define FL_KEY_MEMBER_SIZE(member) (sizeof(((struct fl_flow_key *) 0)->member))
+#define FL_KEY_MEMBER_SIZE(member) FIELD_SIZEOF(struct fl_flow_key, member)
 
 #define FL_KEY_IS_MASKED(mask, member)						\
 	memchr_inv(((char *)mask) + FL_KEY_MEMBER_OFFSET(member),		\
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 0/5] Use FIELD_SIZEOF directly instead of reimplementing its function
From: zhong jiang @ 2018-09-19 10:26 UTC (permalink / raw)
  To: davem; +Cc: jhs, xiyou.wangcong, jiri, netdev, linux-kernel

The issue is detected with the help of Coccinelle.

zhong jiang (5):
  net: iucv: Use FIELD_SIZEOF directly instead of reimplementing its
    function
  net: sched: Use FIELD_SIZEOF directly instead of reimplementing its
    function
  net: core: Use FIELD_SIZEOF directly instead of reimplementing its
    function
  net: qede: Use FIELD_SIZEOF directly instead of reimplementing its
    function
  net: ti: Use FIELD_SIZEOF directly instead of reimplementing its
    function

 drivers/net/ethernet/qlogic/qede/qede.h |  2 +-
 drivers/net/ethernet/ti/cpsw.c          |  6 +++---
 net/core/flow_dissector.c               | 10 +++++-----
 net/iucv/af_iucv.c                      |  2 +-
 net/sched/cls_flower.c                  |  2 +-
 5 files changed, 11 insertions(+), 11 deletions(-)

-- 
1.7.12.4

^ permalink raw reply

* [PATCH net-next] net: marvell: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-19 10:19 UTC (permalink / raw)
  To: davem, thomas.petazzoni, antoine.tenart, maxime.chevallier,
	ymarkman, stefanc, keescook, allen.lkml
  Cc: linux-kernel, netdev, YueHaibing

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/marvell/mvneta.c           | 2 +-
 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 +-
 drivers/net/ethernet/marvell/pxa168_eth.c       | 3 ++-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index fe3edb3..4019479 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2393,7 +2393,7 @@ static int mvneta_tx_frag_process(struct mvneta_port *pp, struct sk_buff *skb,
 }
 
 /* Main tx processing */
-static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mvneta_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct mvneta_port *pp = netdev_priv(dev);
 	u16 txq_id = skb_get_queue_mapping(skb);
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 702fec8..2a897d7 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -2906,7 +2906,7 @@ static int mvpp2_tx_tso(struct sk_buff *skb, struct net_device *dev,
 }
 
 /* Main tx processing */
-static int mvpp2_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mvpp2_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct mvpp2_port *port = netdev_priv(dev);
 	struct mvpp2_tx_queue *txq, *aggr_txq;
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index 3a97306..ff2fea0 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -1260,7 +1260,8 @@ static int pxa168_rx_poll(struct napi_struct *napi, int budget)
 	return work_done;
 }
 
-static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct pxa168_eth_private *pep = netdev_priv(dev);
 	struct net_device_stats *stats = &dev->stats;
-- 
1.8.3.1

^ permalink raw reply related

* Re: [RFC PATCH bpf-next v3 7/7] selftests/bpf: add test cases for queue and stack maps
From: Mauricio Vasquez @ 2018-09-19  4:36 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Alexei Starovoitov, Daniel Borkmann, netdev, Yonghong Song
In-Reply-To: <20180918233238.hct37f4mz5w37urz@ast-mbp>



On 09/18/2018 06:32 PM, Alexei Starovoitov wrote:
> On Tue, Sep 18, 2018 at 06:53:07AM +0200, Mauricio Vasquez B wrote:
>> Two types of tests are done:
>> - test_maps: only userspace api.
>> - test_progs: userspace api and ebpf helpers.
>>
>> Signed-off-by: Mauricio Vasquez B <mauricio.vasquez@polito.it>
>> ---
>>   kernel/bpf/helpers.c                               |    2
>>   tools/lib/bpf/bpf.c                                |   12 ++
>>   tools/lib/bpf/bpf.h                                |    1
>>   tools/testing/selftests/bpf/Makefile               |    5 +
>>   tools/testing/selftests/bpf/bpf_helpers.h          |    7 +
>>   tools/testing/selftests/bpf/test_maps.c            |  130 ++++++++++++++++++++
>>   tools/testing/selftests/bpf/test_progs.c           |   99 +++++++++++++++
>>   tools/testing/selftests/bpf/test_queue_map.c       |    4 +
>>   tools/testing/selftests/bpf/test_queue_stack_map.h |   59 +++++++++
>>   tools/testing/selftests/bpf/test_stack_map.c       |    4 +
>>   10 files changed, 321 insertions(+), 2 deletions(-)
>>   create mode 100644 tools/testing/selftests/bpf/test_queue_map.c
>>   create mode 100644 tools/testing/selftests/bpf/test_queue_stack_map.h
>>   create mode 100644 tools/testing/selftests/bpf/test_stack_map.c
>>
>> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
>> index 5f364e6acaf1..1293cd5240e3 100644
>> --- a/kernel/bpf/helpers.c
>> +++ b/kernel/bpf/helpers.c
>> @@ -76,7 +76,7 @@ const struct bpf_func_proto bpf_map_delete_elem_proto = {
>>   	.arg2_type	= ARG_PTR_TO_MAP_KEY,
>>   };
>>   
>> -BPF_CALL_4(bpf_map_push_elem, struct bpf_map *, map, void *, value, u32 size,
>> +BPF_CALL_4(bpf_map_push_elem, struct bpf_map *, map, void *, value, u32, size,
>>   	   u64, flags)
> part of earlier patch?

Yes, this is wrong on patch 4 and somehow I managed to include the fix 
into this one. Will move to right patch in next version.

>
>>   {
>>   	if (map->value_size != size)
>> diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
>> index 60aa4ca8b2c5..7056b2eb554d 100644
>> --- a/tools/lib/bpf/bpf.c
>> +++ b/tools/lib/bpf/bpf.c
>> @@ -286,6 +286,18 @@ int bpf_map_lookup_elem(int fd, const void *key, void *value)
>>   	return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
>>   }
>>   
>> +int bpf_map_lookup_and_delete_elem(int fd, const void *key, const void *value)
>> +{
>> +	union bpf_attr attr;
>> +
>> +	bzero(&attr, sizeof(attr));
>> +	attr.map_fd = fd;
>> +	attr.key = ptr_to_u64(key);
>> +	attr.value = ptr_to_u64(value);
>> +
>> +	return sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr));
>> +}
>> +
>>   int bpf_map_delete_elem(int fd, const void *key)
>>   {
>>   	union bpf_attr attr;
>> diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
>> index 6f38164b2618..6134ed9517d3 100644
>> --- a/tools/lib/bpf/bpf.h
>> +++ b/tools/lib/bpf/bpf.h
>> @@ -86,6 +86,7 @@ int bpf_map_update_elem(int fd, const void *key, const void *value,
>>   			__u64 flags);
>>   
>>   int bpf_map_lookup_elem(int fd, const void *key, void *value);
>> +int bpf_map_lookup_and_delete_elem(int fd, const void *key, const void *value);
>>   int bpf_map_delete_elem(int fd, const void *key);
>>   int bpf_map_get_next_key(int fd, const void *key, void *next_key);
>>   int bpf_obj_pin(int fd, const char *pathname);
>> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
>> index fff7fb1285fc..ad8a2b8fb738 100644
>> --- a/tools/testing/selftests/bpf/Makefile
>> +++ b/tools/testing/selftests/bpf/Makefile
>> @@ -35,7 +35,7 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
>>   	test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \
>>   	test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \
>>   	get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \
>> -	test_skb_cgroup_id_kern.o
>> +	test_skb_cgroup_id_kern.o test_queue_map.o test_stack_map.o
>>   
>>   # Order correspond to 'make run_tests' order
>>   TEST_PROGS := test_kmod.sh \
>> @@ -110,6 +110,9 @@ CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \
>>   $(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline
>>   $(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline
>>   
>> +$(OUTPUT)/test_queue_map.o: test_queue_stack_map.h
>> +$(OUTPUT)/test_stack_map.o: test_queue_stack_map.h
>> +
>>   BTF_LLC_PROBE := $(shell $(LLC) -march=bpf -mattr=help 2>&1 | grep dwarfris)
>>   BTF_PAHOLE_PROBE := $(shell $(BTF_PAHOLE) --help 2>&1 | grep BTF)
>>   BTF_OBJCOPY_PROBE := $(shell $(LLVM_OBJCOPY) --help 2>&1 | grep -i 'usage.*llvm')
>> diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
>> index e4be7730222d..bdbe8f84023e 100644
>> --- a/tools/testing/selftests/bpf/bpf_helpers.h
>> +++ b/tools/testing/selftests/bpf/bpf_helpers.h
>> @@ -16,6 +16,13 @@ static int (*bpf_map_update_elem)(void *map, void *key, void *value,
>>   	(void *) BPF_FUNC_map_update_elem;
>>   static int (*bpf_map_delete_elem)(void *map, void *key) =
>>   	(void *) BPF_FUNC_map_delete_elem;
>> +static int (*bpf_map_push_elem)(void *map, const void *value, int len,
>> +				unsigned long long flags) =
>> +	(void *) BPF_FUNC_map_push_elem;
>> +static int (*bpf_map_pop_elem)(void *map, void *value, int len) =
>> +	(void *) BPF_FUNC_map_pop_elem;
>> +static int (*bpf_map_peek_elem)(void *map, void *value, int len) =
>> +	(void *) BPF_FUNC_map_peek_elem;
>>   static int (*bpf_probe_read)(void *dst, int size, void *unsafe_ptr) =
>>   	(void *) BPF_FUNC_probe_read;
>>   static unsigned long long (*bpf_ktime_get_ns)(void) =
>> diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
>> index 6f54f84144a0..abb21ea731fa 100644
>> --- a/tools/testing/selftests/bpf/test_maps.c
>> +++ b/tools/testing/selftests/bpf/test_maps.c
>> @@ -15,6 +15,7 @@
>>   #include <string.h>
>>   #include <assert.h>
>>   #include <stdlib.h>
>> +#include <time.h>
>>   
>>   #include <sys/wait.h>
>>   #include <sys/socket.h>
>> @@ -471,6 +472,130 @@ static void test_devmap(int task, void *data)
>>   	close(fd);
>>   }
>>   
>> +static void test_queuemap(int task, void *data)
>> +{
>> +	const int MAP_SIZE = 32;
>> +	__u32 vals[MAP_SIZE + MAP_SIZE/2], val;
>> +	int fd, i;
>> +
>> +	/* Fill test values to be used */
>> +	for (i = 0; i < MAP_SIZE + MAP_SIZE/2; i++)
>> +		vals[i] = rand();
>> +
>> +	/* Invalid key size */
>> +	fd = bpf_create_map(BPF_MAP_TYPE_QUEUE, 4, sizeof(val), MAP_SIZE,
>> +			    map_flags);
>> +	assert(fd < 0 && errno == EINVAL);
>> +
>> +	/* Invalid value size */
>> +	fd = bpf_create_map(BPF_MAP_TYPE_QUEUE, 0, 3, MAP_SIZE,map_flags);
>> +	assert(fd < 0 && errno == EINVAL);
>> +
>> +	fd = bpf_create_map(BPF_MAP_TYPE_QUEUE, 0, sizeof(val), MAP_SIZE,
>> +			    map_flags);
>> +	/* Queue map does not support BPF_F_NO_PREALLOC */
>> +	if (map_flags & BPF_F_NO_PREALLOC) {
>> +		assert(fd < 0 && errno == EINVAL);
>> +		return;
>> +	}
>> +	if (fd < 0) {
>> +		printf("Failed to create queuemap '%s'!\n", strerror(errno));
>> +		exit(1);
>> +	}
>> +
>> +	/* Push MAP_SIZE elements */
>> +	for (i = 0; i < MAP_SIZE; i++)
>> +		assert(bpf_map_update_elem(fd, NULL, &vals[i], 0) == 0);
>> +
>> +	/* Check that element cannot be pushed due to max_entries limit */
>> +	assert(bpf_map_update_elem(fd, NULL, &val, 0) == -1 &&
>> +	       errno == E2BIG);
>> +
>> +	/* Peek element */
>> +	assert(bpf_map_lookup_elem(fd, NULL, &val) == 0 && val == vals[0]);
>> +
>> +	/* Replace half elements */
>> +	for (i = MAP_SIZE; i < MAP_SIZE + MAP_SIZE/2; i++)
>> +		assert(bpf_map_update_elem(fd, NULL, &vals[i], BPF_EXIST) == 0);
>> +
>> +	/* Pop all elements */
>> +	for (i = MAP_SIZE/2; i < MAP_SIZE + MAP_SIZE/2; i++)
>> +		assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) == 0 &&
>> +		       val == vals[i]);
>> +
>> +	/* Check that there are not elements left */
>> +	assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) == -1 &&
>> +	       errno == ENOENT);
>> +
>> +	/* Check that non supported functions set errno to EINVAL */
>> +	assert(bpf_map_delete_elem(fd, NULL) == -1 && errno == EINVAL);
>> +	assert(bpf_map_get_next_key(fd, NULL, NULL) == -1 && errno == EINVAL);
>> +
>> +	close(fd);
>> +}
>> +
>> +static void test_stackmap(int task, void *data)
>> +{
>> +	const int MAP_SIZE = 32;
>> +	__u32 vals[MAP_SIZE + MAP_SIZE/2], val;
>> +	int fd, i;
>> +
>> +	/* Fill test values to be used */
>> +	for (i = 0; i < MAP_SIZE + MAP_SIZE/2; i++)
>> +		vals[i] = rand();
>> +
>> +	/* Invalid key size */
>> +	fd = bpf_create_map(BPF_MAP_TYPE_STACK, 4, sizeof(val), MAP_SIZE,
>> +			    map_flags);
>> +	assert(fd < 0 && errno == EINVAL);
>> +
>> +	/* Invalid value size */
>> +	fd = bpf_create_map(BPF_MAP_TYPE_STACK, 0, 3, MAP_SIZE,map_flags);
>> +	assert(fd < 0 && errno == EINVAL);
>> +
>> +	fd = bpf_create_map(BPF_MAP_TYPE_STACK, 0, sizeof(val), MAP_SIZE,
>> +			    map_flags);
>> +	/* Stack map does not support BPF_F_NO_PREALLOC */
>> +	if (map_flags & BPF_F_NO_PREALLOC) {
>> +		assert(fd < 0 && errno == EINVAL);
>> +		return;
>> +	}
>> +	if (fd < 0) {
>> +		printf("Failed to create stackmap '%s'!\n", strerror(errno));
>> +		exit(1);
>> +	}
>> +
>> +	/* Push MAP_SIZE elements */
>> +	for (i = 0; i < MAP_SIZE; i++)
>> +		assert(bpf_map_update_elem(fd, NULL, &vals[i], 0) == 0);
>> +
>> +	/* Check that element cannot be pushed due to max_entries limit */
>> +	assert(bpf_map_update_elem(fd, NULL, &val, 0) == -1 &&
>> +	       errno == E2BIG);
>> +
>> +	/* Peek element */
>> +	assert(bpf_map_lookup_elem(fd, NULL, &val) == 0 && val == vals[i - 1]);
>> +
>> +	/* Replace half elements */
>> +	for (i = MAP_SIZE; i < MAP_SIZE + MAP_SIZE/2; i++)
>> +		assert(bpf_map_update_elem(fd, NULL, &vals[i], BPF_EXIST) == 0);
>> +
>> +	/* Pop all elements */
>> +	for (i = MAP_SIZE + MAP_SIZE/2 - 1; i >= MAP_SIZE/2; i--)
>> +		assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) == 0 &&
>> +		       val == vals[i]);
>> +
>> +	/* Check that there are not elements left */
>> +	assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) == -1 &&
>> +	       errno == ENOENT);
>> +
>> +	/* Check that non supported functions set errno to EINVAL */
>> +	assert(bpf_map_delete_elem(fd, NULL) == -1 && errno == EINVAL);
>> +	assert(bpf_map_get_next_key(fd, NULL, NULL) == -1 && errno == EINVAL);
>> +
>> +	close(fd);
>> +}
>> +
>>   #include <sys/socket.h>
>>   #include <sys/ioctl.h>
>>   #include <arpa/inet.h>
>> @@ -1430,10 +1555,15 @@ static void run_all_tests(void)
>>   	test_map_wronly();
>>   
>>   	test_reuseport_array();
>> +
>> +	test_queuemap(0, NULL);
>> +	test_stackmap(0, NULL);
>>   }
>>   
>>   int main(void)
>>   {
>> +	srand(time(NULL));
>> +
>>   	map_flags = 0;
>>   	run_all_tests();
>>   
>> diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
>> index 63a671803ed6..a69b9e1e668d 100644
>> --- a/tools/testing/selftests/bpf/test_progs.c
>> +++ b/tools/testing/selftests/bpf/test_progs.c
>> @@ -1698,8 +1698,105 @@ static void test_task_fd_query_tp(void)
>>   				   "sys_enter_read");
>>   }
>>   
>> +enum {
>> +	QUEUE,
>> +	STACK,
>> +};
>> +
>> +static void test_queue_stack_map(int type)
>> +{
>> +	const int MAP_SIZE = 32;
>> +	__u32 vals[MAP_SIZE], duration, retval, size, val;
>> +	int i, err, prog_fd, map_in_fd, map_out_fd;
>> +	char file[32], buf[128];
>> +	struct bpf_object *obj;
>> +	struct iphdr *iph = (void *)buf + sizeof(struct ethhdr);
>> +
>> +	/* Fill test values to be used */
>> +	for (i = 0; i < MAP_SIZE; i++)
>> +		vals[i] = rand();
>> +
>> +	if (type == QUEUE)
>> +		strncpy(file, "./test_queue_map.o", sizeof(file));
>> +	else if (type == STACK)
>> +		strncpy(file, "./test_stack_map.o", sizeof(file));
>> +	else
>> +		return;
>> +
>> +	err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
>> +	if (err) {
>> +		error_cnt++;
>> +		return;
>> +	}
>> +
>> +	map_in_fd = bpf_find_map(__func__, obj, "map_in");
>> +	if (map_in_fd < 0)
>> +		goto out;
>> +
>> +	map_out_fd = bpf_find_map(__func__, obj, "map_out");
>> +	if (map_out_fd < 0)
>> +		goto out;
>> +
>> +	/* Push 32 elements to the input map */
>> +	for (i = 0; i < MAP_SIZE; i++) {
>> +		err = bpf_map_update_elem(map_in_fd, NULL, &vals[i], 0);
>> +		if (err) {
>> +			error_cnt++;
>> +			goto out;
>> +		}
>> +	}
>> +
>> +	/* The eBPF program pushes iph.saddr in the output map,
>> +	 * pops the input map and saves this value in iph.daddr
>> +	 */
>> +	for (i = 0; i < MAP_SIZE; i++) {
>> +		if (type == QUEUE) {
>> +			val = vals[i];
>> +			pkt_v4.iph.saddr = vals[i] * 5;
>> +		} else if (type == STACK) {
>> +			val = vals[MAP_SIZE - 1 - i];
>> +			pkt_v4.iph.saddr = vals[MAP_SIZE - 1 - i] * 5;
>> +		}
>> +
>> +		err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4),
>> +					buf, &size, &retval, &duration);
>> +		if (err || retval || size != sizeof(pkt_v4) ||
>> +		    iph->daddr != val)
>> +			break;
>> +	}
>> +
>> +	CHECK(err || retval || size != sizeof(pkt_v4) || iph->daddr != val,
>> +	      "bpf_map_pop_elem",
>> +	      "err %d errno %d retval %d size %d iph->daddr %u\n",
>> +	      err, errno, retval, size, iph->daddr);
>> +
>> +	/* Queue is empty, program should return TC_ACT_SHOT */
>> +	err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4),
>> +				buf, &size, &retval, &duration);
>> +	CHECK(err || retval != 2 /* TC_ACT_SHOT */|| size != sizeof(pkt_v4),
>> +	      "check-queue-stack-map-empty",
>> +	      "err %d errno %d retval %d size %d\n",
>> +	      err, errno, retval, size);
>> +
>> +	/* Check that the program pushed elements correctly */
>> +	for (i = 0; i < MAP_SIZE; i++) {
>> +		err = bpf_map_lookup_and_delete_elem(map_out_fd, NULL, &val);
>> +		if (err || val != vals[i] * 5)
>> +			break;
>> +	}
>> +
>> +	CHECK(i != MAP_SIZE && (err || val != vals[i] * 5),
>> +	      "bpf_map_push_elem", "err %d value %u\n", err, val);
>> +
>> +out:
>> +	pkt_v4.iph.saddr = 0;
>> +	bpf_object__close(obj);
>> +}
>> +
>>   int main(void)
>>   {
>> +	srand(time(NULL));
>> +
>>   	jit_enabled = is_jit_enabled();
>>   
>>   	test_pkt_access();
>> @@ -1719,6 +1816,8 @@ int main(void)
>>   	test_get_stack_raw_tp();
>>   	test_task_fd_query_rawtp();
>>   	test_task_fd_query_tp();
>> +	test_queue_stack_map(QUEUE);
>> +	test_queue_stack_map(STACK);
>>   
>>   	printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt);
>>   	return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
>> diff --git a/tools/testing/selftests/bpf/test_queue_map.c b/tools/testing/selftests/bpf/test_queue_map.c
>> new file mode 100644
>> index 000000000000..3fdb3b9cb038
>> --- /dev/null
>> +++ b/tools/testing/selftests/bpf/test_queue_map.c
>> @@ -0,0 +1,4 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (c) 2017 Politecnico di Torino
>> +#define MAP_TYPE BPF_MAP_TYPE_QUEUE
>> +#include "test_queue_stack_map.h"
>> diff --git a/tools/testing/selftests/bpf/test_queue_stack_map.h b/tools/testing/selftests/bpf/test_queue_stack_map.h
>> new file mode 100644
>> index 000000000000..23a5b5d60069
>> --- /dev/null
>> +++ b/tools/testing/selftests/bpf/test_queue_stack_map.h
>> @@ -0,0 +1,59 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +// Copyright (c) 2017 Politecnico di Torino
>> +#include <stddef.h>
>> +#include <string.h>
>> +#include <linux/bpf.h>
>> +#include <linux/if_ether.h>
>> +#include <linux/ip.h>
>> +#include <linux/pkt_cls.h>
>> +#include "bpf_helpers.h"
>> +
>> +int _version SEC("version") = 1;
>> +
>> +struct bpf_map_def __attribute__ ((section("maps"), used)) map_in = {
>> +	.type = MAP_TYPE,
>> +	.key_size = 0,
>> +	.value_size = sizeof(__u32),
>> +	.max_entries = 32,
>> +	.map_flags = 0,
>> +};
>> +
>> +struct bpf_map_def __attribute__ ((section("maps"), used)) map_out = {
>> +	.type = MAP_TYPE,
>> +	.key_size = 0,
>> +	.value_size = sizeof(__u32),
>> +	.max_entries = 32,
>> +	.map_flags = 0,
>> +};
>> +
>> +SEC("test")
>> +int _test(struct __sk_buff *skb)
>> +{
>> +	void *data_end = (void *)(long)skb->data_end;
>> +	void *data = (void *)(long)skb->data;
>> +	struct ethhdr *eth = (struct ethhdr *)(data);
>> +	__u32 value;
>> +	int err;
>> +
>> +	if (eth + 1 > data_end)
>> +		return TC_ACT_SHOT;
>> +
>> +	struct iphdr *iph = (struct iphdr *)(eth + 1);
>> +
>> +	if (iph + 1 > data_end)
>> +		return TC_ACT_SHOT;
>> +
>> +	err = bpf_map_pop_elem(&map_in, &value, sizeof(value));
>> +	if (err)
>> +		return TC_ACT_SHOT;
>> +
>> +	iph->daddr = value;
>> +
>> +	err = bpf_map_push_elem(&map_out, &iph->saddr, sizeof(iph->saddr), 0);
>> +	if (err)
>> +		return TC_ACT_SHOT;
> is it possible to add a test for 'peek' helper in reliable way?
> it seems it will alwasy be racy. may be we shouldn't implement peek at all?
>
With the per-value implementation it should not be racy.   Why do you 
say it is seems to be racy?
A very silly test could be to always do peek before pop and check both 
values are the same.

^ permalink raw reply

* Re: [RFC PATCH bpf-next v3 4/7] bpf: add bpf queue and stack maps
From: Mauricio Vasquez @ 2018-09-19  4:28 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Alexei Starovoitov, Daniel Borkmann, netdev, Yonghong Song
In-Reply-To: <20180918232753.2vk6u256ag27cjgo@ast-mbp>



On 09/18/2018 06:27 PM, Alexei Starovoitov wrote:
> On Tue, Sep 18, 2018 at 06:52:51AM +0200, Mauricio Vasquez B wrote:
>> Implement two new kind of maps that support the peek, push and pop
>> operations.
>>
>> A use case for this is to keep track of a pool of elements, like
>> network ports in a SNAT.
>>
>> Signed-off-by: Mauricio Vasquez B <mauricio.vasquez@polito.it>
>> ---
>>   include/linux/bpf.h           |    3
>>   include/linux/bpf_types.h     |    2
>>   include/uapi/linux/bpf.h      |   30 ++++
>>   kernel/bpf/Makefile           |    2
>>   kernel/bpf/core.c             |    3
>>   kernel/bpf/helpers.c          |   98 ++++++++++++++
>>   kernel/bpf/queue_stack_maps.c |  291 +++++++++++++++++++++++++++++++++++++++++
>>   kernel/bpf/verifier.c         |    5 +
>>   net/core/filter.c             |    6 +
>>   9 files changed, 437 insertions(+), 3 deletions(-)
>>   create mode 100644 kernel/bpf/queue_stack_maps.c
>>
>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>> index c63a44381d3f..8e924b5c5a0e 100644
>> --- a/include/linux/bpf.h
>> +++ b/include/linux/bpf.h
>> @@ -807,6 +807,9 @@ static inline int bpf_fd_reuseport_array_update_elem(struct bpf_map *map,
>>   extern const struct bpf_func_proto bpf_map_lookup_elem_proto;
>>   extern const struct bpf_func_proto bpf_map_update_elem_proto;
>>   extern const struct bpf_func_proto bpf_map_delete_elem_proto;
>> +extern const struct bpf_func_proto bpf_map_push_elem_proto;
>> +extern const struct bpf_func_proto bpf_map_pop_elem_proto;
>> +extern const struct bpf_func_proto bpf_map_peek_elem_proto;
>>   
>>   extern const struct bpf_func_proto bpf_get_prandom_u32_proto;
>>   extern const struct bpf_func_proto bpf_get_smp_processor_id_proto;
>> diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
>> index 33f7f574b983..903a446f14c3 100644
>> --- a/include/linux/bpf_types.h
>> +++ b/include/linux/bpf_types.h
>> @@ -67,3 +67,5 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_XSKMAP, xsk_map_ops)
>>   BPF_MAP_TYPE(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, reuseport_array_ops)
>>   #endif
>>   #endif
>> +BPF_MAP_TYPE(BPF_MAP_TYPE_QUEUE, queue_map_ops)
>> +BPF_MAP_TYPE(BPF_MAP_TYPE_STACK, stack_map_ops)
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 4cda584c6640..c899386dcb2b 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -128,6 +128,8 @@ enum bpf_map_type {
>>   	BPF_MAP_TYPE_SOCKHASH,
>>   	BPF_MAP_TYPE_CGROUP_STORAGE,
>>   	BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
>> +	BPF_MAP_TYPE_QUEUE,
>> +	BPF_MAP_TYPE_STACK,
>>   };
>>   
>>   enum bpf_prog_type {
>> @@ -460,6 +462,29 @@ union bpf_attr {
>>    * 	Return
>>    * 		0 on success, or a negative error in case of failure.
>>    *
>> + * int bpf_map_push_elem(struct bpf_map *map, const void *value, u32 len,
>> + * 			 u64 flags)
> since we're passing <=8 byte value there is no need for pointer and len.
> Lower bits of 'u64 value' would be faster and easier to use from bpf prog side.
I have the doubt between both solutions, will change it to only u64 value.

>> + * 	Description
>> + * 		Push an element *value* in *map*. *flags* is one of:
>> + *
>> + * 		**BPF_EXIST**
>> + * 		If the queue/stack is full, the oldest element is removed to
>> + * 		make room for this.
>> + * 	Return
>> + * 		0 on success, or a negative error in case of failure.
>> + *
>> + * int bpf_map_pop_elem(struct bpf_map *map, void *value, u32 len)
>> + * 	Description
>> + * 		Pop an element from *map*.
>> + * Return
>> + * 		0 on success, or a negative error in case of failure.
>> + *
>> + * int bpf_map_peek_elem(struct bpf_map *map, void *value, u32 len)
> for pop/peak helpers the 'void *value' makes sense,
> but 'len' doesn't need to be there and doesn't need to be checked in runtime.
> Verifier should be able to do that.

You are right, ARG_PTR_TO_MAP_VALUE should do these tests automatically 
based on map->value_size.

> More below.
>
>> + * 	Description
>> + * 		Get an element from *map* without removing it.
>> + * Return
>> + * 		0 on success, or a negative error in case of failure.
>> + *
>>    * int bpf_probe_read(void *dst, u32 size, const void *src)
>>    * 	Description
>>    * 		For tracing programs, safely attempt to read *size* bytes from
>> @@ -2227,7 +2252,10 @@ union bpf_attr {
>>   	FN(get_current_cgroup_id),	\
>>   	FN(get_local_storage),		\
>>   	FN(sk_select_reuseport),	\
>> -	FN(skb_ancestor_cgroup_id),
>> +	FN(skb_ancestor_cgroup_id),	\
>> +	FN(map_push_elem),		\
>> +	FN(map_pop_elem),		\
>> +	FN(map_peek_elem),
>>   
>>   /* integer value in 'imm' field of BPF_CALL instruction selects which helper
>>    * function eBPF program intends to call
>> diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
>> index e656bce87c8f..2d77bc5b2aca 100644
>> --- a/kernel/bpf/Makefile
>> +++ b/kernel/bpf/Makefile
>> @@ -3,7 +3,7 @@ obj-y := core.o
>>   
>>   obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o
>>   obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o
>> -obj-$(CONFIG_BPF_SYSCALL) += local_storage.o
>> +obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o
>>   obj-$(CONFIG_BPF_SYSCALL) += disasm.o
>>   obj-$(CONFIG_BPF_SYSCALL) += btf.o
>>   ifeq ($(CONFIG_NET),y)
>> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
>> index 3f5bf1af0826..8d2db076d123 100644
>> --- a/kernel/bpf/core.c
>> +++ b/kernel/bpf/core.c
>> @@ -1783,6 +1783,9 @@ BPF_CALL_0(bpf_user_rnd_u32)
>>   const struct bpf_func_proto bpf_map_lookup_elem_proto __weak;
>>   const struct bpf_func_proto bpf_map_update_elem_proto __weak;
>>   const struct bpf_func_proto bpf_map_delete_elem_proto __weak;
>> +const struct bpf_func_proto bpf_map_push_elem_proto __weak;
>> +const struct bpf_func_proto bpf_map_pop_elem_proto __weak;
>> +const struct bpf_func_proto bpf_map_peek_elem_proto __weak;
>>   
>>   const struct bpf_func_proto bpf_get_prandom_u32_proto __weak;
>>   const struct bpf_func_proto bpf_get_smp_processor_id_proto __weak;
>> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
>> index 1991466b8327..5f364e6acaf1 100644
>> --- a/kernel/bpf/helpers.c
>> +++ b/kernel/bpf/helpers.c
>> @@ -76,6 +76,104 @@ const struct bpf_func_proto bpf_map_delete_elem_proto = {
>>   	.arg2_type	= ARG_PTR_TO_MAP_KEY,
>>   };
>>   
>> +BPF_CALL_4(bpf_map_push_elem, struct bpf_map *, map, void *, value, u32 size,
>> +	   u64, flags)
>> +{
>> +	if (map->value_size != size)
>> +		return -EINVAL;
>> +
>> +	return map->ops->map_update_elem(map, NULL, value, flags);
>> +}
>> +
>> +const struct bpf_func_proto bpf_map_push_elem_proto = {
>> +	.func		= bpf_map_push_elem,
>> +	.gpl_only	= false,
>> +	.pkt_access	= true,
>> +	.ret_type	= RET_INTEGER,
>> +	.arg1_type	= ARG_CONST_MAP_PTR,
>> +	.arg2_type	= ARG_PTR_TO_MEM,
>> +	.arg3_type	= ARG_CONST_SIZE,
>> +	.arg4_type	= ARG_ANYTHING,
>> +};
>> +
>> +BPF_CALL_3(bpf_map_pop_elem, struct bpf_map *, map, void *, value, u32, size)
>> +{
>> +	void *ptr;
>> +
>> +	if (map->value_size != size)
>> +		return -EINVAL;
>> +
>> +	ptr = map->ops->map_lookup_and_delete_elem(map, NULL);
>> +	if (!ptr)
>> +		return -ENOENT;
>> +
>> +	switch (size) {
>> +	case 1:
>> +		*(u8 *) value = *(u8 *) ptr;
>> +		break;
>> +	case 2:
>> +		*(u16 *) value = *(u16 *) ptr;
>> +		break;
>> +	case 4:
>> +		*(u32 *) value = *(u32 *) ptr;
>> +		break;
>> +	case 8:
>> +		*(u64 *) value = *(u64 *) ptr;
>> +		break;
> this is inefficient. can we pass value ptr into ops and let it populate it?

I don't think so, doing that implies that look_and_delete will be a 
per-value op, while other ops in maps are per-reference.
For instance, how to change it in the case of peek helper that is using 
the lookup operation?, we cannot change the signature of the lookup 
operation.

This is something that worries me a little bit, we are creating new 
per-value helpers based on already existing per-reference operations, 
this is not probably the cleanest way.  Here we are at the beginning of 
the discussion once again, how should we map helpers and syscalls to ops.

What about creating pop/peek/push ops, mapping helpers one to one and 
adding some logic into syscall.c to call the correct operation in case 
the map is stack/queue?
Syscall mapping would be:
bpf_map_lookup_elem() -> peek
bpf_map_lookup_and_delete_elem() -> pop
bpf_map_update_elem() -> push

Does it make sense?

>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +const struct bpf_func_proto bpf_map_pop_elem_proto = {
>> +	.func		= bpf_map_pop_elem,
>> +	.gpl_only	= false,
>> +	.pkt_access	= true,
>> +	.ret_type	= RET_INTEGER,
>> +	.arg1_type	= ARG_CONST_MAP_PTR,
>> +	.arg2_type	= ARG_PTR_TO_UNINIT_MEM,
>> +	.arg3_type	= ARG_CONST_SIZE,
>> +};
>> +
>> +BPF_CALL_3(bpf_map_peek_elem, struct bpf_map *, map, void *, value, u32, size)
>> +{
>> +	void *ptr;
>> +
>> +	if (map->value_size != size)
>> +		return -EINVAL;
>> +
>> +	ptr = map->ops->map_lookup_elem(map, NULL);
>> +	if (!ptr)
>> +		return -ENOENT;
>> +
>> +	switch (size) {
>> +	case 1:
>> +		*(u8 *) value = *(u8 *) ptr;
>> +		break;
>> +	case 2:
>> +		*(u16 *) value = *(u16 *) ptr;
>> +		break;
>> +	case 4:
>> +		*(u32 *) value = *(u32 *) ptr;
>> +		break;
>> +	case 8:
>> +		*(u64 *) value = *(u64 *) ptr;
>> +		break;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +const struct bpf_func_proto bpf_map_peek_elem_proto = {
>> +	.func		= bpf_map_pop_elem,
>> +	.gpl_only	= false,
>> +	.pkt_access	= true,
>> +	.ret_type	= RET_INTEGER,
>> +	.arg1_type	= ARG_CONST_MAP_PTR,
>> +	.arg2_type	= ARG_PTR_TO_UNINIT_MEM,
>> +	.arg3_type	= ARG_CONST_SIZE,
>> +};
>> +
>>   const struct bpf_func_proto bpf_get_prandom_u32_proto = {
>>   	.func		= bpf_user_rnd_u32,
>>   	.gpl_only	= false,
>> diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c
>> new file mode 100644
>> index 000000000000..10c081f3f02b
>> --- /dev/null
>> +++ b/kernel/bpf/queue_stack_maps.c
>> @@ -0,0 +1,291 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * queue_stack_maps.c: BPF queue and stack maps
>> + *
>> + * Copyright (c) 2018 Politecnico di Torino
>> + */
>> +#include <linux/bpf.h>
>> +#include <linux/list.h>
>> +#include <linux/slab.h>
>> +#include "percpu_freelist.h"
>> +
>> +#define QUEUE_STACK_CREATE_FLAG_MASK \
>> +	(BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY)
>> +
>> +
>> +struct bpf_queue_stack {
>> +	struct bpf_map map;
>> +	raw_spinlock_t lock;
>> +	u32 head, tail;
>> +	u32 index_mask;
>> +	u32 count;
>> +
>> +	char elements[0] __aligned(8);
>> +};
>> +
>> +static struct bpf_queue_stack *bpf_queue_stack(struct bpf_map *map)
>> +{
>> +	return container_of(map, struct bpf_queue_stack, map);
>> +}
>> +
>> +static bool queue_stack_map_is_empty(struct bpf_queue_stack *qs)
>> +{
>> +	return qs->count == 0;
>> +}
>> +
>> +static bool queue_stack_map_is_full(struct bpf_queue_stack *qs)
>> +{
>> +	return qs->count == qs->map.max_entries;
>> +}
>> +
>> +/* Called from syscall */
>> +static int queue_stack_map_alloc_check(union bpf_attr *attr)
>> +{
>> +	/* check sanity of attributes */
>> +	if (attr->max_entries == 0 || attr->key_size != 0 ||
>> +	    (attr->value_size != 1 && attr->value_size != 2 &&
>> +	    attr->value_size != 4 && attr->value_size != 8) ||
>> +	    attr->map_flags & ~QUEUE_STACK_CREATE_FLAG_MASK)
>> +		return -EINVAL;
>> +
>> +	if (attr->value_size > KMALLOC_MAX_SIZE)
>> +		/* if value_size is bigger, the user space won't be able to
>> +		 * access the elements.
>> +		 */
>> +		return -E2BIG;
>> +
>> +	return 0;
>> +}
>> +
>> +static struct bpf_map *queue_stack_map_alloc(union bpf_attr *attr)
>> +{
>> +	int ret, numa_node = bpf_map_attr_numa_node(attr);
>> +	u32 max_entries, value_size, index_mask;
>> +	u64 queue_size, cost, mask64;
>> +	struct bpf_queue_stack *qs;
>> +
>> +	max_entries = attr->max_entries;
>> +	value_size = attr->value_size;
>> +
>> +	/* From arraymap.c:
>> +	 * On 32 bit archs roundup_pow_of_two() with max_entries that has
>> +	 * upper most bit set in u32 space is undefined behavior due to
>> +	 * resulting 1U << 32, so do it manually here in u64 space.
>> +	 */
>> +	mask64 = fls_long(max_entries - 1);
>> +	mask64 = 1ULL << mask64;
>> +	mask64 -= 1;
>> +
>> +	index_mask = mask64;
>> +
>> +	/* Round up queue size to nearest power of 2 */
>> +	max_entries = index_mask + 1;
>> +	/* Check for overflows. */
>> +	if (max_entries < attr->max_entries)
>> +		return ERR_PTR(-E2BIG);
>> +
>> +	queue_size = sizeof(*qs) + (u64) value_size * max_entries;
>> +
>> +	cost = queue_size;
>> +	if (cost >= U32_MAX - PAGE_SIZE)
>> +		return ERR_PTR(-E2BIG);
>> +
>> +	cost = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT;
>> +
>> +	ret = bpf_map_precharge_memlock(cost);
>> +	if (ret < 0)
>> +		return ERR_PTR(ret);
>> +
>> +	qs = bpf_map_area_alloc(queue_size, numa_node);
>> +	if (!qs)
>> +		return ERR_PTR(-ENOMEM);
>> +
>> +	memset(qs, 0, sizeof(*qs));
>> +
>> +	bpf_map_init_from_attr(&qs->map, attr);
>> +
>> +	qs->map.pages = cost;
>> +	qs->index_mask = index_mask;
>> +
>> +	raw_spin_lock_init(&qs->lock);
>> +
>> +	return &qs->map;
>> +}
>> +
>> +/* Called when map->refcnt goes to zero, either from workqueue or from syscall */
>> +static void queue_stack_map_free(struct bpf_map *map)
>> +{
>> +	struct bpf_queue_stack *qs = bpf_queue_stack(map);
>> +
>> +	/* at this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0,
>> +	 * so the programs (can be more than one that used this map) were
>> +	 * disconnected from events. Wait for outstanding critical sections in
>> +	 * these programs to complete
>> +	 */
>> +	synchronize_rcu();
>> +
>> +	bpf_map_area_free(qs);
>> +}
>> +
>> +static void *__queue_map_lookup(struct bpf_map *map, bool delete)
>> +{
>> +	struct bpf_queue_stack *qs = bpf_queue_stack(map);
>> +	unsigned long flags;
>> +	void *ptr = NULL;
>> +
>> +	raw_spin_lock_irqsave(&qs->lock, flags);
>> +
>> +	if (queue_stack_map_is_empty(qs))
>> +		goto out;
>> +
>> +	ptr = &qs->elements[qs->tail * qs->map.value_size];
>> +
>> +	if (delete) {
>> +		qs->tail = (qs->tail + 1) & qs->index_mask;
>> +		qs->count--;
>> +	}
>> +
>> +out:
>> +	raw_spin_unlock_irqrestore(&qs->lock, flags);
>> +	return ptr;
>> +}
>> +
>> +
>> +static void *__stack_map_lookup(struct bpf_map *map, bool delete)
>> +{
>> +	struct bpf_queue_stack *qs = bpf_queue_stack(map);
>> +	unsigned long flags;
>> +	void *ptr = NULL;
>> +	u32 index;
>> +
>> +	raw_spin_lock_irqsave(&qs->lock, flags);
>> +
>> +	if (queue_stack_map_is_empty(qs))
>> +		goto out;
>> +
>> +	index = (qs->head - 1) & qs->index_mask;
>> +	ptr = &qs->elements[index * qs->map.value_size];
>> +
>> +	if (delete) {
>> +		qs->head = (qs->head - 1) & qs->index_mask;
>> +		qs->count--;
>> +	}
>> +
>> +out:
>> +	raw_spin_unlock_irqrestore(&qs->lock, flags);
> here it's racing with another cpu accessing the same map.
> rcu doesn't protect from this particular qs->element being reused
> by another cpu.
>
>> +	return ptr;
> say, stack is full. one cpu is doing pop(), getting this ptr,
> while another cpu doing push() and overwriting this memory.
Yes, are right.  The lock must be held until the copy is done.  The 
solution to it depends on what ops we agree to create.
>> +}
>> +
>> +/* Called from syscall or from eBPF program */
>> +static void *queue_map_lookup_elem(struct bpf_map *map, void *key)
>> +{
>> +	return __queue_map_lookup(map, false);
>> +}
>> +
>> +/* Called from syscall or from eBPF program */
>> +static void *stack_map_lookup_elem(struct bpf_map *map, void *key)
>> +{
>> +	return __stack_map_lookup(map, false);
>> +}
>> +
>> +/* Called from syscall or from eBPF program */
>> +static void *queue_map_lookup_and_delete_elem(struct bpf_map *map, void *key)
>> +{
>> +	return __queue_map_lookup(map, true);
>> +}
>> +
>> +/* Called from syscall or from eBPF program */
>> +static void *stack_map_lookup_and_delete_elem(struct bpf_map *map, void *key)
>> +{
>> +	return __stack_map_lookup(map, true);
>> +}
>> +
>> +/* Called from syscall or from eBPF program */
>> +static int queue_stack_map_update_elem(struct bpf_map *map, void *key,
>> +				       void *value, u64 flags)
>> +{
>> +	struct bpf_queue_stack *qs = bpf_queue_stack(map);
>> +	unsigned long irq_flags;
>> +	int err = 0;
>> +	void *dst;
>> +
>> +	/* BPF_EXIST is used to force making room for a new element in case the
>> +	 * map is full
>> +	 */
>> +	bool replace = (flags & BPF_EXIST);
>> +
>> +	/* Check supported flags for queue and stqueue_map_is_preallocack maps */
>> +	if (flags & BPF_NOEXIST || flags > BPF_EXIST)
>> +		return -EINVAL;
>> +
>> +	raw_spin_lock_irqsave(&qs->lock, irq_flags);
>> +
>> +	if (queue_stack_map_is_full(qs)) {
>> +		if (!replace) {
>> +			err = -E2BIG;
>> +			goto out;
>> +		}
>> +		/* advance tail pointer to overwrite oldest element */
>> +		qs->tail = (qs->tail + 1) & qs->index_mask;
>> +		qs->count--;
>> +	}
>> +
>> +	dst = &qs->elements[qs->head * qs->map.value_size];
>> +
>> +	switch (qs->map.value_size) {
>> +	case 1:
>> +		*(u8 *) dst = *(u8 *) value;
>> +		break;
>> +	case 2:
>> +		*(u16 *) dst = *(u16 *) value;
>> +		break;
>> +	case 4:
>> +		*(u32 *) dst = *(u32 *) value;
>> +		break;
>> +	case 8:
>> +		*(u64 *) dst = *(u64 *) value;
>> +		break;
>> +	}
>> +
>> +	qs->head = (qs->head + 1) & qs->index_mask;
>> +	qs->count++;
>> +
>> +out:
>> +	raw_spin_unlock_irqrestore(&qs->lock, irq_flags);
>> +	return err;
>> +}
>> +
>> +/* Called from syscall or from eBPF program */
>> +static int queue_stack_map_delete_elem(struct bpf_map *map, void *key)
>> +{
>> +	return -EINVAL;
>> +}
>> +
>> +/* Called from syscall */
>> +static int queue_stack_map_get_next_key(struct bpf_map *map, void *key,
>> +					void *next_key)
>> +{
>> +	return -EINVAL;
>> +}
>> +
>> +const struct bpf_map_ops queue_map_ops = {
>> +	.map_alloc_check = queue_stack_map_alloc_check,
>> +	.map_alloc = queue_stack_map_alloc,
>> +	.map_free = queue_stack_map_free,
>> +	.map_lookup_elem = queue_map_lookup_elem,
>> +	.map_lookup_and_delete_elem = queue_map_lookup_and_delete_elem,
>> +	.map_update_elem = queue_stack_map_update_elem,
>> +	.map_delete_elem = queue_stack_map_delete_elem,
>> +	.map_get_next_key = queue_stack_map_get_next_key,
>> +};
>> +
>> +const struct bpf_map_ops stack_map_ops = {
>> +	.map_alloc_check = queue_stack_map_alloc_check,
>> +	.map_alloc = queue_stack_map_alloc,
>> +	.map_free = queue_stack_map_free,
>> +	.map_lookup_elem = stack_map_lookup_elem,
>> +	.map_lookup_and_delete_elem = stack_map_lookup_and_delete_elem,
>> +	.map_update_elem = queue_stack_map_update_elem,
>> +	.map_delete_elem = queue_stack_map_delete_elem,
>> +	.map_get_next_key = queue_stack_map_get_next_key,
>> +};
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index f4ff0c569e54..b9e005188f0e 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -2369,7 +2369,10 @@ record_func_map(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
>>   	if (func_id != BPF_FUNC_tail_call &&
>>   	    func_id != BPF_FUNC_map_lookup_elem &&
>>   	    func_id != BPF_FUNC_map_update_elem &&
>> -	    func_id != BPF_FUNC_map_delete_elem)
>> +	    func_id != BPF_FUNC_map_delete_elem &&
>> +	    func_id != BPF_FUNC_map_push_elem &&
>> +	    func_id != BPF_FUNC_map_pop_elem &&
>> +	    func_id != BPF_FUNC_map_peek_elem)
>>   		return 0;
>>   
>>   	if (meta->map_ptr == NULL) {
>> diff --git a/net/core/filter.c b/net/core/filter.c
>> index feb578506009..c7b73376c23a 100644
>> --- a/net/core/filter.c
>> +++ b/net/core/filter.c
>> @@ -4839,6 +4839,12 @@ bpf_base_func_proto(enum bpf_func_id func_id)
>>   		return &bpf_map_update_elem_proto;
>>   	case BPF_FUNC_map_delete_elem:
>>   		return &bpf_map_delete_elem_proto;
>> +	case BPF_FUNC_map_push_elem:
>> +		return &bpf_map_push_elem_proto;
>> +	case BPF_FUNC_map_pop_elem:
>> +		return &bpf_map_pop_elem_proto;
>> +	case BPF_FUNC_map_peek_elem:
>> +		return &bpf_map_peek_elem_proto;
>>   	case BPF_FUNC_get_prandom_u32:
>>   		return &bpf_get_prandom_u32_proto;
>>   	case BPF_FUNC_get_smp_processor_id:
>>

^ permalink raw reply

* [PATCH] net: iucv: Use FIELD_SIZEOF directly instead of reimplementing its function
From: zhong jiang @ 2018-09-19  9:52 UTC (permalink / raw)
  To: davem; +Cc: ubraun, jwi, netdev, linux-kernel

FIELD_SIZEOF is defined as a macro to calculate the specified vaule. Therefore,
We prefer to use the macro rather than calculating its vaule.

Signed-off-by: zhong jiang <zhongjiang@huawei.com>
---
 net/iucv/af_iucv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index e2f16a0..5b68ee9 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -48,7 +48,7 @@
 static const u8 iprm_shutdown[8] =
 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
 
-#define TRGCLS_SIZE	(sizeof(((struct iucv_message *)0)->class))
+#define TRGCLS_SIZE	FIELD_SIZEOF(struct iucv_message, class)
 
 #define __iucv_sock_wait(sk, condition, timeo, ret)			\
 do {									\
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH net-next 3/3] net: mvneta: do not explicitly set the carrier state in open
From: Antoine Tenart @ 2018-09-19  9:39 UTC (permalink / raw)
  To: davem, linux, andrew, f.fainelli
  Cc: Antoine Tenart, netdev, linux-kernel, thomas.petazzoni,
	maxime.chevallier, gregory.clement, miquel.raynal, nadavh,
	stefanc, ymarkman, mw
In-Reply-To: <20180919093933.24411-1-antoine.tenart@bootlin.com>

This patch removes the explicit call to netif_carrier_off() in
mvneta_open() as this is already handled in phylink_start().

Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
 drivers/net/ethernet/marvell/mvneta.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index fe3edb3c2bf4..89ed1df7b3e7 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -3791,9 +3791,6 @@ static int mvneta_open(struct net_device *dev)
 			goto err_free_online_hp;
 	}
 
-	/* In default link is down */
-	netif_carrier_off(pp->dev);
-
 	ret = mvneta_mdio_probe(pp);
 	if (ret < 0) {
 		netdev_err(dev, "cannot probe MDIO bus\n");
-- 
2.17.1

^ permalink raw reply related

* [PATCH net-next 2/3] net: mvpp2: do not explicitly set the carrier state in open
From: Antoine Tenart @ 2018-09-19  9:39 UTC (permalink / raw)
  To: davem, linux, andrew, f.fainelli
  Cc: Antoine Tenart, netdev, linux-kernel, thomas.petazzoni,
	maxime.chevallier, gregory.clement, miquel.raynal, nadavh,
	stefanc, ymarkman, mw
In-Reply-To: <20180919093933.24411-1-antoine.tenart@bootlin.com>

This patch removes the explicit call to netif_carrier_off() in PPv2's
open() path, as this is now handled in phylink_start().

Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index af6e62c6579b..21da835b1c52 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -3196,7 +3196,6 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
 		mvpp22_mode_reconfigure(port);
 
 	if (port->phylink) {
-		netif_carrier_off(port->dev);
 		phylink_start(port->phylink);
 	} else {
 		/* Phylink isn't used as of now for ACPI, so the MAC has to be
-- 
2.17.1

^ permalink raw reply related

* [PATCH net-next 0/3] net: phy: phylink: ensure the carrier is off when starting phylink
From: Antoine Tenart @ 2018-09-19  9:39 UTC (permalink / raw)
  To: davem, linux, andrew, f.fainelli
  Cc: Antoine Tenart, netdev, linux-kernel, thomas.petazzoni,
	maxime.chevallier, gregory.clement, miquel.raynal, nadavh,
	stefanc, ymarkman, mw

Hi Russell,

Following the discussion we had regarding the phylink issue related to
the carrier link state not being off when starting phylink, I sent a fix
patch a few days ago for the PPv2 driver:
https://lkml.org/lkml/2018/9/14/633

The idea was to send a patch which could go to the stable branches, but
a better solution would be to directly call netif_carrier_off() from
within phylink_start(). This is the aim of this series.

Thanks!
Antoine

Antoine Tenart (3):
  net: phy: phylink: ensure the carrier is off when starting phylink
  net: mvpp2: do not explicitly set the carrier state in open
  net: mvneta: do not explicitly set the carrier state in open

 drivers/net/ethernet/marvell/mvneta.c           | 3 ---
 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 -
 drivers/net/phy/phylink.c                       | 3 +++
 3 files changed, 3 insertions(+), 4 deletions(-)

-- 
2.17.1

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox