Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6ca4b80 authored by Harout Hedeshian's avatar Harout Hedeshian
Browse files

net: rmnet_data: Enhanced counters



Added performance counters to various key places in RmNet Data
data path.

CRs-Fixed: 600629
Change-Id: Iba50c86665e181e09525e9538a540e09e526e16f
Signed-off-by: default avatarHarout Hedeshian <harouth@codeaurora.org>
parent 90d52535
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,4 +8,5 @@ rmnet_data-y += rmnet_data_vnd.o
rmnet_data-y		 += rmnet_data_handlers.o
rmnet_data-y		 += rmnet_map_data.o
rmnet_data-y		 += rmnet_map_command.o
rmnet_data-y		 += rmnet_data_stats.o
obj-$(CONFIG_RMNET_DATA) += rmnet_data.o
+19 −12
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "rmnet_data_config.h"
#include "rmnet_data_vnd.h"
#include "rmnet_map.h"
#include "rmnet_data_stats.h"

RMNET_LOG_MODULE(RMNET_DATA_LOGMASK_HANDLER);

@@ -149,7 +150,7 @@ static rx_handler_result_t rmnet_bridge_handler(struct sk_buff *skb,
	if (!ep->egress_dev) {
		LOGD("Missing egress device for packet arriving on %s",
		     skb->dev->name);
		kfree_skb(skb);
		rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_BRDG_NO_EGRESS);
	} else {
		rmnet_egress_handler(skb, ep);
	}
@@ -193,7 +194,7 @@ static rx_handler_result_t __rmnet_deliver_skb(struct sk_buff *skb,

	default:
		LOGD("Unkown ep mode %d", ep->rmnet_mode);
		kfree_skb(skb);
		rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_DELIVER_NO_EP);
		return RX_HANDLER_CONSUMED;
	}
}
@@ -220,7 +221,7 @@ static rx_handler_result_t rmnet_ingress_deliver_packet(struct sk_buff *skb,
	if (!(config->local_ep.refcount)) {
		LOGD("Packet on %s has no local endpoint configuration",
			skb->dev->name);
		kfree_skb(skb);
		rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_IPINGRESS_NO_EP);
		return RX_HANDLER_CONSUMED;
	}

@@ -258,7 +259,7 @@ static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb,
	if (mux_id >= RMNET_DATA_MAX_LOGICAL_EP) {
		LOGD("Got packet on %s with bad mux id %d",
			skb->dev->name, mux_id);
		kfree_skb(skb);
		rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_MAPINGRESS_BAD_MUX);
			return RX_HANDLER_CONSUMED;
	}

@@ -268,7 +269,7 @@ static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb,
		LOGD("Packet on %s:%d; has no logical endpoint config",
		     skb->dev->name, mux_id);

		kfree_skb(skb);
		rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_MAPINGRESS_MUX_NO_EP);
		return RX_HANDLER_CONSUMED;
	}

@@ -305,11 +306,12 @@ static rx_handler_result_t rmnet_map_ingress_handler(struct sk_buff *skb,

	if (config->ingress_data_format & RMNET_INGRESS_FORMAT_DEAGGREGATION) {
		while ((skbn = rmnet_map_deaggregate(skb, config)) != 0) {
			LOGD("co=%d", co);
			_rmnet_map_ingress_handler(skbn, config);
			co++;
		}
		kfree_skb(skb);
		LOGD("De-aggregated %d packets", co);
		rmnet_stats_deagg_pkts(co);
		rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_MAPINGRESS_AGGBUF);
		rc = RX_HANDLER_CONSUMED;
	} else {
		rc = _rmnet_map_ingress_handler(skb, config);
@@ -431,7 +433,8 @@ rx_handler_result_t rmnet_ingress_handler(struct sk_buff *skb)
			} else {
				LOGM("MAP command packet on %s; %s", dev->name,
				     "Not configured for MAP commands");
				kfree_skb(skb);
				rmnet_kfree_skb(skb,
				   RMNET_STATS_SKBFREE_INGRESS_NOT_EXPECT_MAPC);
				return RX_HANDLER_CONSUMED;
			}
		} else {
@@ -446,7 +449,8 @@ rx_handler_result_t rmnet_ingress_handler(struct sk_buff *skb)
			} else {
				LOGD("MAP packet on %s; MAP not set",
					dev->name);
				kfree_skb(skb);
				rmnet_kfree_skb(skb,
				   RMNET_STATS_SKBFREE_INGRESS_NOT_EXPECT_MAPD);
				rc = RX_HANDLER_CONSUMED;
			}
			break;
@@ -497,6 +501,7 @@ void rmnet_egress_handler(struct sk_buff *skb,
{
	struct rmnet_phys_ep_conf_s *config;
	struct net_device *orig_dev;
	int rc;
	orig_dev = skb->dev;
	skb->dev = ep->egress_dev;

@@ -524,7 +529,7 @@ void rmnet_egress_handler(struct sk_buff *skb,
		default:
			LOGD("MAP egress failed on packet on %s",
			     skb->dev->name);
			kfree_skb(skb);
			rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_EGR_MAPFAIL);
			return;
		}
	}
@@ -533,8 +538,10 @@ void rmnet_egress_handler(struct sk_buff *skb,
		rmnet_vnd_tx_fixup(skb, orig_dev);

	rmnet_print_packet(skb, skb->dev->name, 't');
	if (dev_queue_xmit(skb) != 0) {
	rc = dev_queue_xmit(skb);
	if (rc != 0) {
		LOGD("Failed to queue packet for transmission on [%s]",
		      skb->dev->name);
	}
	rmnet_stats_queue_xmit(rc, RMNET_STATS_QUEUE_XMIT_EGRESS);
}
+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *
 * RMNET Data statistics
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include "rmnet_data_private.h"
#include "rmnet_data_stats.h"

enum rmnet_deagg_e {
	RMNET_STATS_AGG_BUFF,
	RMNET_STATS_AGG_PKT,
	RMNET_STATS_AGG_MAX
};

static DEFINE_SPINLOCK(rmnet_skb_free_lock);
unsigned long int skb_free[RMNET_STATS_SKBFREE_MAX];
module_param_array(skb_free, ulong, 0, S_IRUGO);
MODULE_PARM_DESC(skb_free, "SKBs dropped or freed");

static DEFINE_SPINLOCK(rmnet_queue_xmit_lock);
unsigned long int queue_xmit[RMNET_STATS_QUEUE_XMIT_MAX*2];
module_param_array(queue_xmit, ulong, 0, S_IRUGO);
MODULE_PARM_DESC(queue_xmit, "SKBs queued");

static DEFINE_SPINLOCK(rmnet_deagg_count);
unsigned long int deagg_count[RMNET_STATS_AGG_MAX];
module_param_array(deagg_count, ulong, 0, S_IRUGO);
MODULE_PARM_DESC(deagg_count, "SKBs queued");

static DEFINE_SPINLOCK(rmnet_agg_count);
unsigned long int agg_count[RMNET_STATS_AGG_MAX];
module_param_array(agg_count, ulong, 0, S_IRUGO);
MODULE_PARM_DESC(agg_count, "SKBs queued");

void rmnet_kfree_skb(struct sk_buff *skb, unsigned int reason)
{
	unsigned long flags;

	if (reason >= RMNET_STATS_SKBFREE_MAX)
		reason = RMNET_STATS_SKBFREE_UNKNOWN;

	spin_lock_irqsave(&rmnet_skb_free_lock, flags);
	skb_free[reason]++;
	spin_unlock_irqrestore(&rmnet_skb_free_lock, flags);

	if (skb)
		kfree_skb(skb);
}

void rmnet_stats_queue_xmit(int rc, unsigned int reason)
{
	unsigned long flags;

	if (rc != 0)
		reason += RMNET_STATS_QUEUE_XMIT_MAX;
	if (reason >= RMNET_STATS_QUEUE_XMIT_MAX*2)
		reason = RMNET_STATS_SKBFREE_UNKNOWN;

	spin_lock_irqsave(&rmnet_queue_xmit_lock, flags);
	queue_xmit[reason]++;
	spin_unlock_irqrestore(&rmnet_queue_xmit_lock, flags);
}

void rmnet_stats_agg_pkts(int aggcount)
{
	unsigned long flags;

	spin_lock_irqsave(&rmnet_agg_count, flags);
	agg_count[RMNET_STATS_AGG_BUFF]++;
	agg_count[RMNET_STATS_AGG_PKT] += aggcount;
	spin_unlock_irqrestore(&rmnet_agg_count, flags);
}

void rmnet_stats_deagg_pkts(int aggcount)
{
	unsigned long flags;

	spin_lock_irqsave(&rmnet_deagg_count, flags);
	deagg_count[RMNET_STATS_AGG_BUFF]++;
	deagg_count[RMNET_STATS_AGG_PKT] += aggcount;
	spin_unlock_irqrestore(&rmnet_deagg_count, flags);
}
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *
 * RMNET Data statistics
 *
 */

#ifndef _RMNET_DATA_STATS_H_
#define _RMNET_DATA_STATS_H_

enum rmnet_skb_free_e {
	RMNET_STATS_SKBFREE_UNKNOWN,
	RMNET_STATS_SKBFREE_BRDG_NO_EGRESS,
	RMNET_STATS_SKBFREE_DELIVER_NO_EP,
	RMNET_STATS_SKBFREE_IPINGRESS_NO_EP,
	RMNET_STATS_SKBFREE_MAPINGRESS_BAD_MUX,
	RMNET_STATS_SKBFREE_MAPINGRESS_MUX_NO_EP,
	RMNET_STATS_SKBFREE_MAPINGRESS_AGGBUF,
	RMNET_STATS_SKBFREE_INGRESS_NOT_EXPECT_MAPD,
	RMNET_STATS_SKBFREE_INGRESS_NOT_EXPECT_MAPC,
	RMNET_STATS_SKBFREE_EGR_MAPFAIL,
	RMNET_STATS_SKBFREE_VND_NO_EGRESS,
	RMNET_STATS_SKBFREE_MAPC_BAD_MUX,
	RMNET_STATS_SKBFREE_MAPC_MUX_NO_EP,
	RMNET_STATS_SKBFREE_AGG_CPY_EXPAND,
	RMNET_STATS_SKBFREE_AGG_INTO_BUFF,
	RMNET_STATS_SKBFREE_DEAGG_MALFORMED,
	RMNET_STATS_SKBFREE_DEAGG_CLONE_FAIL,
	RMNET_STATS_SKBFREE_DEAGG_UNKOWN_IP_TYP,
	RMNET_STATS_SKBFREE_MAX
};

enum rmnet_queue_xmit_e {
	RMNET_STATS_QUEUE_XMIT_UNKNOWN,
	RMNET_STATS_QUEUE_XMIT_EGRESS,
	RMNET_STATS_QUEUE_XMIT_AGG_FILL_BUFFER,
	RMNET_STATS_QUEUE_XMIT_AGG_TIMEOUT,
	RMNET_STATS_QUEUE_XMIT_AGG_CPY_EXP_FAIL,
	RMNET_STATS_QUEUE_XMIT_MAX
};

void rmnet_kfree_skb(struct sk_buff *skb, unsigned int reason);
void rmnet_stats_queue_xmit(int rc, unsigned int reason);
void rmnet_stats_deagg_pkts(int aggcount);
void rmnet_stats_agg_pkts(int aggcount);
#endif /* _RMNET_DATA_STATS_H_ */
+2 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include "rmnet_data_private.h"
#include "rmnet_map.h"
#include "rmnet_data_vnd.h"
#include "rmnet_data_stats.h"

RMNET_LOG_MODULE(RMNET_DATA_LOGMASK_VND);

@@ -177,7 +178,7 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
		rmnet_egress_handler(skb, &dev_conf->local_ep);
	} else {
		dev->stats.tx_dropped++;
		kfree_skb(skb);
		rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_VND_NO_EGRESS);
	}
	return NETDEV_TX_OK;
}
Loading