diff options
author | Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> | 2014-06-16 16:37:05 (GMT) |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-06-19 19:49:24 (GMT) |
commit | 7c0acf868d2e470c9d6a40091acf8d6444c01b57 (patch) | |
tree | 20b89ce3af714877c6444a41b9a036c919e75265 /drivers/net | |
parent | 67c3e1b41efe4dd400f444c6dccc4538b627758c (diff) | |
download | linux-7c0acf868d2e470c9d6a40091acf8d6444c01b57.tar.xz |
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: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/debugfs.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/txrx.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wil6210.h | 3 |
3 files changed, 23 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index d90aa28..9c11023 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -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++) { struct vring *vring = &(wil->vring_tx[i]); + struct vring_tx_data *txdata = &wil->vring_tx_data[i]; + if (vring->va) { int cid = wil->vring2cid_tid[i][0]; 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; int avail = vring->size - used - 1; 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); - seq_printf(s, "\n%pM CID %d TID %d [%3d|%3d]\n", - wil->sta[cid].addr, cid, tid, used, avail); + seq_printf(s, "\n%pM CID %d TID %d [%3d|%3d] idle %3d%%\n", + wil->sta[cid].addr, cid, tid, used, avail, + (int)((idle*100)/total)); + wil_print_vring(s, wil, name, vring, '_', 'H'); } } diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index c08d041..0318cd2 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -881,6 +881,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, int nr_frags = skb_shinfo(skb)->nr_frags; uint f = 0; int vring_index = vring - wil->vring_tx; + struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index]; uint i = swhead; 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, (const void *)d, sizeof(*d), false); + if (wil_vring_is_empty(vring)) /* performance monitoring */ + txdata->idle += get_cycles() - txdata->last_idle; + /* advance swhead */ wil_vring_advance_head(vring, nr_frags + 1); 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); + txdata->last_idle = get_cycles(); + } if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring)) netif_tx_wake_all_queues(wil_to_ndev(wil)); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 793675e..ede4c9f 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -20,6 +20,7 @@ #include <linux/netdevice.h> #include <linux/wireless.h> #include <net/cfg80211.h> +#include <linux/timex.h> #define WIL_NAME "wil6210" @@ -251,7 +252,7 @@ struct vring { */ struct vring_tx_data { int enabled; - + cycles_t idle, last_idle, begin; }; enum { /* for wil6210_priv.status */ |