Skip to contentSkip to conversation

net: qualcomm: rmnet: Add 64 bit stats and GRO

PATCH In review Subash Abhinov Kasiviswanathan 2 participants 6 messages Oct 26, 2017 – Oct 27, 2017

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v2 cover net: qualcomm: rmnet: Add 64 bit stats and GRO

This series adds support for 64 bit per cpu stats and GRO

Patches 1-2 are cleanups of return code and a redundant condition Patch 3 adds support for 64 bit per cpu stats
Patch 4 adds support for GRO using GRO cells

v1->v2: Since gro_cells_init() could potentially fail, move it from device setup to ndo_init() as mentioned by Eric.

Subash Abhinov Kasiviswanathan (4):
net: qualcomm: rmnet: Fix the return value of rmnet_rx_handler()
net: qualcomm: rmnet: Always assign rmnet dev in deaggregation path
net: qualcomm: rmnet: Add support for 64 bit stats
net: qualcomm: rmnet: Add support for GRO

 drivers/net/ethernet/qualcomm/rmnet/Kconfig        |  1 +
 drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h | 16 +++++
 .../net/ethernet/qualcomm/rmnet/rmnet_handlers.c   | 38 +++++-----
 drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h    |  3 +-
 .../ethernet/qualcomm/rmnet/rmnet_map_command.c    |  4 +-
 drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c    | 84 ++++++++++++++++++++--
 6 files changed, 114 insertions(+), 32 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH v2 1/4 net: qualcomm: rmnet: Fix the return value of rmnet_rx_handler()

Since packet is always consumed by rmnet_rx_handler(), we always return RX_HANDLER_CONSUMED. There is no need to pass on this value through multiple functions.

---
 .../net/ethernet/qualcomm/rmnet/rmnet_handlers.c   | 31 +++++++++-------------
 drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h    |  3 +--
 .../ethernet/qualcomm/rmnet/rmnet_map_command.c    |  4 +--
 3 files changed, 14 insertions(+), 24 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +12 -19
index df3d2d1..5dd186d 100644
@@ -43,7 +43,7 @@ static void rmnet_set_skb_proto(struct sk_buff *skb)
 
 /* Generic handler */
 
-static rx_handler_result_t
+static void
 rmnet_deliver_skb(struct sk_buff *skb)
 {
 	skb_reset_transport_header(skb);
@@ -53,12 +53,11 @@ static void rmnet_set_skb_proto(struct sk_buff *skb)
 	skb->pkt_type = PACKET_HOST;
 	skb_set_mac_header(skb, 0);
 	netif_receive_skb(skb);
-	return RX_HANDLER_CONSUMED;
 }
 
 /* MAP handler */
 
-static rx_handler_result_t
+static void
 __rmnet_map_ingress_handler(struct sk_buff *skb,
 			    struct rmnet_port *port)
 {
@@ -91,31 +90,27 @@ static void rmnet_set_skb_proto(struct sk_buff *skb)
 	skb_pull(skb, sizeof(struct rmnet_map_header));
 	skb_trim(skb, len);
 	rmnet_set_skb_proto(skb);
-	return rmnet_deliver_skb(skb);
+	rmnet_deliver_skb(skb);
+	return;
 
 free_skb:
 	kfree_skb(skb);
-	return RX_HANDLER_CONSUMED;
 }
 
-static rx_handler_result_t
+static void
 rmnet_map_ingress_handler(struct sk_buff *skb,
 			  struct rmnet_port *port)
 {
 	struct sk_buff *skbn;
-	int rc;
 
 	if (port->ingress_data_format & RMNET_INGRESS_FORMAT_DEAGGREGATION) {
 		while ((skbn = rmnet_map_deaggregate(skb)) != NULL)
 			__rmnet_map_ingress_handler(skbn, port);
 
 		consume_skb(skb);
-		rc = RX_HANDLER_CONSUMED;
 	} else {
-		rc = __rmnet_map_ingress_handler(skb, port);
+		__rmnet_map_ingress_handler(skb, port);
 	}
-
-	return rc;
 }
 
 static int rmnet_map_egress_handler(struct sk_buff *skb,
@@ -149,15 +144,13 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
 	return RMNET_MAP_SUCCESS;
 }
 
-static rx_handler_result_t
+static void
 rmnet_bridge_handler(struct sk_buff *skb, struct net_device *bridge_dev)
 {
 	if (bridge_dev) {
 		skb->dev = bridge_dev;
 		dev_queue_xmit(skb);
 	}
-
-	return RX_HANDLER_CONSUMED;
 }
 
 /* Ingress / Egress Entry Points */
@@ -168,13 +161,12 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
  */
 rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb)
 {
-	int rc = RX_HANDLER_CONSUMED;
 	struct sk_buff *skb = *pskb;
 	struct rmnet_port *port;
 	struct net_device *dev;
 
 	if (!skb)
-		return RX_HANDLER_CONSUMED;
+		goto done;
 
 	dev = skb->dev;
 	port = rmnet_get_port(dev);
@@ -182,14 +174,15 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb)
 	switch (port->rmnet_mode) {
 	case RMNET_EPMODE_VND:
 		if (port->ingress_data_format & RMNET_INGRESS_FORMAT_MAP)
-			rc = rmnet_map_ingress_handler(skb, port);
+			rmnet_map_ingress_handler(skb, port);
 		break;
 	case RMNET_EPMODE_BRIDGE:
-		rc = rmnet_bridge_handler(skb, port->bridge_ep);
+		rmnet_bridge_handler(skb, port->bridge_ep);
 		break;
 	}
 
-	return rc;
+done:
+	return RX_HANDLER_CONSUMED;
 }
 
 /* Modifies packet as per logical endpoint configuration and egress data format
drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +1 -2
index ce2302c..3af3fe7 100644
@@ -80,7 +80,6 @@ struct rmnet_map_header {
 struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb);
 struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb,
 						  int hdrlen, int pad);
-rx_handler_result_t rmnet_map_command(struct sk_buff *skb,
-				      struct rmnet_port *port);
+void rmnet_map_command(struct sk_buff *skb, struct rmnet_port *port);
 
 #endif /* _RMNET_MAP_H_ */
drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c +1 -3
index 74d362f..51e6049 100644
@@ -76,8 +76,7 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
 /* Process MAP command frame and send N/ACK message as appropriate. Message cmd
  * name is decoded here and appropriate handler is called.
  */
-rx_handler_result_t rmnet_map_command(struct sk_buff *skb,
-				      struct rmnet_port *port)
+void rmnet_map_command(struct sk_buff *skb, struct rmnet_port *port)
 {
 	struct rmnet_map_control_command *cmd;
 	unsigned char command_name;
@@ -102,5 +101,4 @@ rx_handler_result_t rmnet_map_command(struct sk_buff *skb,
 	}
 	if (rc == RMNET_MAP_COMMAND_ACK)
 		rmnet_map_send_ack(skb, rc);
-	return RX_HANDLER_CONSUMED;
 }
Signature · 1 line
1.9.1
#2 lore raw

PATCH v2 2/4 net: qualcomm: rmnet: Always assign rmnet dev in deaggregation path

In reply to Subash Abhinov Kasiviswanathan

The rmnet device needs to assigned for all packets in the deaggregation path based on the mux id, so the check is not needed.

---
 drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +1 -2
index 5dd186d..1ea9783 100644
@@ -83,8 +83,7 @@ static void rmnet_set_skb_proto(struct sk_buff *skb)
 	if (!ep)
 		goto free_skb;
 
-	if (port->ingress_data_format & RMNET_INGRESS_FORMAT_DEMUXING)
-		skb->dev = ep->egress_dev;
+	skb->dev = ep->egress_dev;
 
 	/* Subtract MAP header */
 	skb_pull(skb, sizeof(struct rmnet_map_header));
Signature · 1 line
1.9.1
#3 lore raw

PATCH v2 3/4 net: qualcomm: rmnet: Add support for 64 bit stats

In reply to Subash Abhinov Kasiviswanathan

Implement 64 bit per cpu stats.

---
 drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h | 14 ++++
 drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c    | 76 ++++++++++++++++++++--
 2 files changed, 85 insertions(+), 5 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +14 -0
index 60115e6..9586703d 100644
@@ -41,9 +41,23 @@ struct rmnet_port {
 
 extern struct rtnl_link_ops rmnet_link_ops;
 
+struct rmnet_vnd_stats {
+	u64 rx_pkts;
+	u64 rx_bytes;
+	u64 tx_pkts;
+	u64 tx_bytes;
+	u32 tx_drops;
+};
+
+struct rmnet_pcpu_stats {
+	struct rmnet_vnd_stats stats;
+	struct u64_stats_sync syncp;
+};
+
 struct rmnet_priv {
 	u8 mux_id;
 	struct net_device *real_dev;
+	struct rmnet_pcpu_stats __percpu *pcpu_stats;
 };
 
 struct rmnet_port *rmnet_get_port(struct net_device *real_dev);
drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +71 -5

104 lines not on this page · raw message

Signature · 1 line
1.9.1
#4 lore raw

PATCH v2 4/4 net: qualcomm: rmnet: Add support for GRO

In reply to Subash Abhinov Kasiviswanathan

Add gro_cells so that rmnet devices can call gro_cells_receive instead of netif_receive_skb.

---
 drivers/net/ethernet/qualcomm/rmnet/Kconfig          | 1 +
 drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h   | 2 ++
 drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 4 +++-
 drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c      | 8 ++++++++
 4 files changed, 14 insertions(+), 1 deletion(-)
drivers/net/ethernet/qualcomm/rmnet/Kconfig +1 -0
index 6e2587a..9bb06d2 100644
@@ -5,6 +5,7 @@
 menuconfig RMNET
 	tristate "RmNet MAP driver"
 	default n
+	select GRO_CELLS
 	---help---
 	  If you select this, you will enable the RMNET module which is used
 	  for handling data in the multiplexing and aggregation protocol (MAP)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +2 -0
index 9586703d..c19259e 100644
@@ -14,6 +14,7 @@
  */
 
 #include <linux/skbuff.h>
+#include <net/gro_cells.h>
 
 #ifndef _RMNET_CONFIG_H_
 #define _RMNET_CONFIG_H_
@@ -58,6 +59,7 @@ struct rmnet_priv {
 	u8 mux_id;
 	struct net_device *real_dev;
 	struct rmnet_pcpu_stats __percpu *pcpu_stats;
+	struct gro_cells gro_cells;
 };
 
 struct rmnet_port *rmnet_get_port(struct net_device *real_dev);
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +3 -1
index 1ea9783..29842cc 100644
@@ -46,13 +46,15 @@ static void rmnet_set_skb_proto(struct sk_buff *skb)
 static void
 rmnet_deliver_skb(struct sk_buff *skb)
 {
+	struct rmnet_priv *priv = netdev_priv(skb->dev);
+
 	skb_reset_transport_header(skb);
 	skb_reset_network_header(skb);
 	rmnet_vnd_rx_fixup(skb, skb->dev);
 
 	skb->pkt_type = PACKET_HOST;
 	skb_set_mac_header(skb, 0);
-	netif_receive_skb(skb);
+	gro_cells_receive(&priv->gro_cells, skb);
 }
 
 /* MAP handler */
drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +8 -0
index b0befa1..9caa5e3 100644
@@ -87,11 +87,18 @@ static int rmnet_vnd_get_iflink(const struct net_device *dev)
 static int rmnet_vnd_init(struct net_device *dev)
 {
 	struct rmnet_priv *priv = netdev_priv(dev);
+	int err;
 
 	priv->pcpu_stats = alloc_percpu(struct rmnet_pcpu_stats);
 	if (!priv->pcpu_stats)
 		return -ENOMEM;
 
+	err = gro_cells_init(&priv->gro_cells, dev);
+	if (err) {
+		free_percpu(priv->pcpu_stats);
+		return err;
+	}
+
 	return 0;
 }
 
@@ -99,6 +106,7 @@ static void rmnet_vnd_uninit(struct net_device *dev)
 {
 	struct rmnet_priv *priv = netdev_priv(dev);
 
+	gro_cells_destroy(&priv->gro_cells);
 	free_percpu(priv->pcpu_stats);
 }
 
Signature · 1 line
1.9.1
maintainer
#5 lore raw
In reply to Subash Abhinov Kasiviswanathan

From: Subash Abhinov Kasiviswanathan <[email protected]>
Date: Thu, 26 Oct 2017 11:06:45 -0600

Quoted 8 lines

This series adds support for 64 bit per cpu stats and GRO

Patches 1-2 are cleanups of return code and a redundant condition Patch 3 adds support for 64 bit per cpu stats
Patch 4 adds support for GRO using GRO cells

v1->v2: Since gro_cells_init() could potentially fail, move it from device setup to ndo_init() as mentioned by Eric.

Series applied, thank you.