iwlwifi: make data frame tracing optional
When tracing in iwlwifi, we get all data. Most of the time, we don't need it, and it just takes up a lot of extra space in the trace. Make this optional by recording the data into two separate trace events if it is needed. Without it, record only the content of non-data and EAPOL TX frames. As a result, tracing without the data tracepoints will record meta information including the 802.11 headers for all frames but will not record the contents of data frames to reduce trace overhead. Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
此提交包含在:
@@ -25,6 +25,39 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include "iwl-trans.h"
|
||||
#if !defined(__IWLWIFI_DEVICE_TRACE)
|
||||
static inline bool iwl_trace_data(struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
|
||||
if (ieee80211_is_data(hdr->frame_control))
|
||||
return skb->protocol != cpu_to_be16(ETH_P_PAE);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
|
||||
void *rxbuf, size_t len)
|
||||
{
|
||||
struct iwl_cmd_header *cmd = (void *)((u8 *)rxbuf + sizeof(__le32));
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
||||
if (cmd->cmd != trans->rx_mpdu_cmd)
|
||||
return len;
|
||||
|
||||
hdr = (void *)((u8 *)cmd + sizeof(struct iwl_cmd_header) +
|
||||
trans->rx_mpdu_cmd_hdr_size);
|
||||
if (!ieee80211_is_data(hdr->frame_control))
|
||||
return len;
|
||||
/* maybe try to identify EAPOL frames? */
|
||||
return sizeof(__le32) + sizeof(*cmd) + trans->rx_mpdu_cmd_hdr_size +
|
||||
ieee80211_hdrlen(hdr->frame_control);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define __IWLWIFI_DEVICE_TRACE
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
@@ -234,6 +267,48 @@ TRACE_EVENT(iwlwifi_dbg,
|
||||
TP_printk("%s", (char *)__get_dynamic_array(msg))
|
||||
);
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM iwlwifi_data
|
||||
|
||||
TRACE_EVENT(iwlwifi_dev_tx_data,
|
||||
TP_PROTO(const struct device *dev,
|
||||
struct sk_buff *skb,
|
||||
void *data, size_t data_len),
|
||||
TP_ARGS(dev, skb, data, data_len),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
|
||||
__dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
if (iwl_trace_data(skb))
|
||||
memcpy(__get_dynamic_array(data), data, data_len);
|
||||
),
|
||||
TP_printk("[%s] TX frame data", __get_str(dev))
|
||||
);
|
||||
|
||||
TRACE_EVENT(iwlwifi_dev_rx_data,
|
||||
TP_PROTO(const struct device *dev,
|
||||
const struct iwl_trans *trans,
|
||||
void *rxbuf, size_t len),
|
||||
TP_ARGS(dev, trans, rxbuf, len),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
|
||||
__dynamic_array(u8, data,
|
||||
len - iwl_rx_trace_len(trans, rxbuf, len))
|
||||
),
|
||||
TP_fast_assign(
|
||||
size_t offs = iwl_rx_trace_len(trans, rxbuf, len);
|
||||
DEV_ASSIGN;
|
||||
if (offs < len)
|
||||
memcpy(__get_dynamic_array(data),
|
||||
((u8 *)rxbuf) + offs, len - offs);
|
||||
),
|
||||
TP_printk("[%s] TX frame data", __get_str(dev))
|
||||
);
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM iwlwifi
|
||||
|
||||
@@ -270,25 +345,28 @@ TRACE_EVENT(iwlwifi_dev_hcmd,
|
||||
);
|
||||
|
||||
TRACE_EVENT(iwlwifi_dev_rx,
|
||||
TP_PROTO(const struct device *dev, void *rxbuf, size_t len),
|
||||
TP_ARGS(dev, rxbuf, len),
|
||||
TP_PROTO(const struct device *dev, const struct iwl_trans *trans,
|
||||
void *rxbuf, size_t len),
|
||||
TP_ARGS(dev, trans, rxbuf, len),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__dynamic_array(u8, rxbuf, len)
|
||||
__dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, rxbuf, len))
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
memcpy(__get_dynamic_array(rxbuf), rxbuf, len);
|
||||
memcpy(__get_dynamic_array(rxbuf), rxbuf,
|
||||
iwl_rx_trace_len(trans, rxbuf, len));
|
||||
),
|
||||
TP_printk("[%s] RX cmd %#.2x",
|
||||
__get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4])
|
||||
);
|
||||
|
||||
TRACE_EVENT(iwlwifi_dev_tx,
|
||||
TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen,
|
||||
TP_PROTO(const struct device *dev, struct sk_buff *skb,
|
||||
void *tfd, size_t tfdlen,
|
||||
void *buf0, size_t buf0_len,
|
||||
void *buf1, size_t buf1_len),
|
||||
TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
|
||||
TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
|
||||
@@ -301,14 +379,15 @@ TRACE_EVENT(iwlwifi_dev_tx,
|
||||
* for the possible padding).
|
||||
*/
|
||||
__dynamic_array(u8, buf0, buf0_len)
|
||||
__dynamic_array(u8, buf1, buf1_len)
|
||||
__dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
__entry->framelen = buf0_len + buf1_len;
|
||||
memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
|
||||
memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
|
||||
memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
|
||||
if (!iwl_trace_data(skb))
|
||||
memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
|
||||
),
|
||||
TP_printk("[%s] TX %.2x (%zu bytes)",
|
||||
__get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
|
||||
|
新增問題並參考
封鎖使用者