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

Commit 7c0acf86 authored by Vladimir Kondratiev's avatar Vladimir Kondratiev Committed by John W. Linville
Browse files

wil6210: Tx performance monitoring



For performance monitoring, trace time intervals when Tx vring
is idle/not idle. Use CPU cycle counter for this, because jiffies is
too rough, and other precise time measurement methods involve
overhead while get_cycles() should be fast.
This used to provide some estimation for percentage when Tx vring
was idle, i.e. when hardware is under-utilized.
Estimation is not precise because of many reasons - CPU frequency scaling,
grt_cycles() may be per core etc. But still, it is good estimation

Signed-off-by: default avatarVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 67c3e1b4
Loading
Loading
Loading
Loading
+14 −2
Original line number Original line Diff line number Diff line
@@ -69,6 +69,8 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)


	for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
	for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
		struct vring *vring = &(wil->vring_tx[i]);
		struct vring *vring = &(wil->vring_tx[i]);
		struct vring_tx_data *txdata = &wil->vring_tx_data[i];

		if (vring->va) {
		if (vring->va) {
			int cid = wil->vring2cid_tid[i][0];
			int cid = wil->vring2cid_tid[i][0];
			int tid = wil->vring2cid_tid[i][1];
			int tid = wil->vring2cid_tid[i][1];
@@ -78,10 +80,20 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
				   % vring->size;
				   % vring->size;
			int avail = vring->size - used - 1;
			int avail = vring->size - used - 1;
			char name[10];
			char name[10];
			/* performance monitoring */
			cycles_t now = get_cycles();
			cycles_t idle = txdata->idle;
			cycles_t total = now - txdata->begin;

			txdata->begin = now;
			txdata->idle = 0ULL;

			snprintf(name, sizeof(name), "tx_%2d", i);
			snprintf(name, sizeof(name), "tx_%2d", i);


			seq_printf(s, "\n%pM CID %d TID %d [%3d|%3d]\n",
			seq_printf(s, "\n%pM CID %d TID %d [%3d|%3d] idle %3d%%\n",
				   wil->sta[cid].addr, cid, tid, used, avail);
				   wil->sta[cid].addr, cid, tid, used, avail,
				   (int)((idle*100)/total));

			wil_print_vring(s, wil, name, vring, '_', 'H');
			wil_print_vring(s, wil, name, vring, '_', 'H');
		}
		}
	}
	}
+7 −1
Original line number Original line Diff line number Diff line
@@ -881,6 +881,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
	int nr_frags = skb_shinfo(skb)->nr_frags;
	int nr_frags = skb_shinfo(skb)->nr_frags;
	uint f = 0;
	uint f = 0;
	int vring_index = vring - wil->vring_tx;
	int vring_index = vring - wil->vring_tx;
	struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index];
	uint i = swhead;
	uint i = swhead;
	dma_addr_t pa;
	dma_addr_t pa;


@@ -953,6 +954,9 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
	wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
	wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
			  (const void *)d, sizeof(*d), false);
			  (const void *)d, sizeof(*d), false);


	if (wil_vring_is_empty(vring)) /* performance monitoring */
		txdata->idle += get_cycles() - txdata->last_idle;

	/* advance swhead */
	/* advance swhead */
	wil_vring_advance_head(vring, nr_frags + 1);
	wil_vring_advance_head(vring, nr_frags + 1);
	wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
	wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
@@ -1133,8 +1137,10 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
		}
		}
	}
	}


	if (wil_vring_is_empty(vring))
	if (wil_vring_is_empty(vring)) { /* performance monitoring */
		wil_dbg_txrx(wil, "Ring[%2d] empty\n", ringid);
		wil_dbg_txrx(wil, "Ring[%2d] empty\n", ringid);
		txdata->last_idle = get_cycles();
	}


	if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring))
	if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring))
		netif_tx_wake_all_queues(wil_to_ndev(wil));
		netif_tx_wake_all_queues(wil_to_ndev(wil));
+2 −1
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <net/cfg80211.h>
#include <linux/timex.h>


#define WIL_NAME "wil6210"
#define WIL_NAME "wil6210"


@@ -251,7 +252,7 @@ struct vring {
 */
 */
struct vring_tx_data {
struct vring_tx_data {
	int enabled;
	int enabled;

	cycles_t idle, last_idle, begin;
};
};


enum { /* for wil6210_priv.status */
enum { /* for wil6210_priv.status */