qcacmn: Add per CPU interrupt statistics
Add per CPU per copy engine interrupt statistics. Change-Id: I1619f0db3314ae3d915284459f2b191f31fc2190 CRs-Fixed: 1017437
This commit is contained in:

committed by
Nandini Suresh

parent
8f7d421854
commit
b70bd731ec
@@ -505,7 +505,8 @@ QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev,
|
|||||||
enum qdf_bus_type bus_type,
|
enum qdf_bus_type bus_type,
|
||||||
enum hif_enable_type type);
|
enum hif_enable_type type);
|
||||||
void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type);
|
void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type);
|
||||||
|
void hif_display_stats(struct hif_opaque_softc *hif_ctx);
|
||||||
|
void hif_clear_stats(struct hif_opaque_softc *hif_ctx);
|
||||||
#ifdef FEATURE_RUNTIME_PM
|
#ifdef FEATURE_RUNTIME_PM
|
||||||
struct hif_pm_runtime_lock;
|
struct hif_pm_runtime_lock;
|
||||||
int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx);
|
int hif_pm_runtime_get(struct hif_opaque_softc *hif_ctx);
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include "qdf_atomic.h"
|
#include "qdf_atomic.h"
|
||||||
#include "qdf_lock.h"
|
#include "qdf_lock.h"
|
||||||
#include "hif_main.h"
|
#include "hif_main.h"
|
||||||
|
#include "qdf_util.h"
|
||||||
|
|
||||||
#define CE_HTT_T2H_MSG 1
|
#define CE_HTT_T2H_MSG 1
|
||||||
#define CE_HTT_H2T_MSG 4
|
#define CE_HTT_H2T_MSG 4
|
||||||
@@ -111,6 +112,10 @@ struct ce_tasklet_entry {
|
|||||||
void *hif_ce_state;
|
void *hif_ce_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ce_intr_stats {
|
||||||
|
uint32_t ce_per_cpu[CE_COUNT_MAX][QDF_MAX_AVAILABLE_CPU];
|
||||||
|
};
|
||||||
|
|
||||||
struct HIF_CE_state {
|
struct HIF_CE_state {
|
||||||
struct hif_softc ol_sc;
|
struct hif_softc ol_sc;
|
||||||
bool started;
|
bool started;
|
||||||
@@ -135,6 +140,7 @@ struct HIF_CE_state {
|
|||||||
|
|
||||||
/* Copy Engine used for Diagnostic Accesses */
|
/* Copy Engine used for Diagnostic Accesses */
|
||||||
struct CE_handle *ce_diag;
|
struct CE_handle *ce_diag;
|
||||||
|
struct ce_intr_stats stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -256,6 +256,63 @@ static irqreturn_t hif_snoc_interrupt_handler(int irq, void *context)
|
|||||||
return ce_dispatch_interrupt(icnss_get_ce_id(irq), tasklet_entry);
|
return ce_dispatch_interrupt(icnss_get_ce_id(irq), tasklet_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hif_ce_increment_interrupt_count() - update ce stats
|
||||||
|
* @hif_ce_state: ce state
|
||||||
|
* @ce_id: ce id
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
hif_ce_increment_interrupt_count(struct HIF_CE_state *hif_ce_state, int ce_id)
|
||||||
|
{
|
||||||
|
int cpu_id = qdf_get_cpu();
|
||||||
|
|
||||||
|
hif_ce_state->stats.ce_per_cpu[ce_id][cpu_id]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hif_display_ce_stats() - display ce stats
|
||||||
|
* @hif_ce_state: ce state
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state)
|
||||||
|
{
|
||||||
|
#define STR_SIZE 128
|
||||||
|
uint8_t i, j, pos;
|
||||||
|
char str_buffer[STR_SIZE];
|
||||||
|
int size, ret;
|
||||||
|
|
||||||
|
qdf_print("CE interrupt statistics:");
|
||||||
|
for (i = 0; i < CE_COUNT_MAX; i++) {
|
||||||
|
size = STR_SIZE;
|
||||||
|
pos = 0;
|
||||||
|
qdf_print("CE id: %d", i);
|
||||||
|
for (j = 0; j < QDF_MAX_AVAILABLE_CPU; j++) {
|
||||||
|
ret = snprintf(str_buffer + pos, size, "[%d]: %d",
|
||||||
|
j, hif_ce_state->stats.ce_per_cpu[i][j]);
|
||||||
|
if (ret <= 0 || ret >= size)
|
||||||
|
break;
|
||||||
|
size -= ret;
|
||||||
|
pos += ret;
|
||||||
|
}
|
||||||
|
qdf_print("%s", str_buffer);
|
||||||
|
}
|
||||||
|
#undef STR_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hif_clear_ce_stats() - clear ce stats
|
||||||
|
* @hif_ce_state: ce state
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
void hif_clear_ce_stats(struct HIF_CE_state *hif_ce_state)
|
||||||
|
{
|
||||||
|
qdf_mem_zero(&hif_ce_state->stats, sizeof(struct ce_intr_stats));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ce_dispatch_interrupt() - dispatch an interrupt to a processing context
|
* ce_dispatch_interrupt() - dispatch an interrupt to a processing context
|
||||||
* @ce_id: ce_id
|
* @ce_id: ce_id
|
||||||
@@ -283,6 +340,7 @@ irqreturn_t ce_dispatch_interrupt(int ce_id,
|
|||||||
hif_irq_disable(scn, ce_id);
|
hif_irq_disable(scn, ce_id);
|
||||||
qdf_atomic_inc(&scn->active_tasklet_cnt);
|
qdf_atomic_inc(&scn->active_tasklet_cnt);
|
||||||
hif_record_ce_desc_event(scn, ce_id, HIF_IRQ_EVENT, NULL, NULL, 0);
|
hif_record_ce_desc_event(scn, ce_id, HIF_IRQ_EVENT, NULL, NULL, 0);
|
||||||
|
hif_ce_increment_interrupt_count(hif_ce_state, ce_id);
|
||||||
if (hif_napi_enabled(hif_hdl, ce_id))
|
if (hif_napi_enabled(hif_hdl, ce_id))
|
||||||
hif_napi_schedule(hif_hdl, ce_id);
|
hif_napi_schedule(hif_hdl, ce_id);
|
||||||
else
|
else
|
||||||
|
@@ -35,4 +35,6 @@ QDF_STATUS ce_register_irq(struct HIF_CE_state *hif_ce_state, uint32_t mask);
|
|||||||
QDF_STATUS ce_unregister_irq(struct HIF_CE_state *hif_ce_state, uint32_t mask);
|
QDF_STATUS ce_unregister_irq(struct HIF_CE_state *hif_ce_state, uint32_t mask);
|
||||||
irqreturn_t ce_dispatch_interrupt(int irq,
|
irqreturn_t ce_dispatch_interrupt(int irq,
|
||||||
struct ce_tasklet_entry *tasklet_entry);
|
struct ce_tasklet_entry *tasklet_entry);
|
||||||
|
void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state);
|
||||||
|
void hif_clear_ce_stats(struct HIF_CE_state *hif_ce_state);
|
||||||
#endif /* __CE_TASKLET_H__ */
|
#endif /* __CE_TASKLET_H__ */
|
||||||
|
@@ -266,3 +266,21 @@ hif_dummy_mask_interrupt_call(struct hif_softc *hif_sc)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hif_dummy_display_stats - dummy call
|
||||||
|
* hif_ctx: hif context
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
void hif_dummy_display_stats(struct hif_softc *hif_ctx)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hif_dummy_clear_stats - dummy call
|
||||||
|
* hif_ctx: hif context
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
void hif_dummy_clear_stats(struct hif_softc *hif_ctx)
|
||||||
|
{}
|
||||||
|
@@ -53,3 +53,5 @@ void hif_dummy_ipa_get_ce_resource(struct hif_softc *hif_sc,
|
|||||||
uint32_t *sr_ring_size,
|
uint32_t *sr_ring_size,
|
||||||
qdf_dma_addr_t *reg_paddr);
|
qdf_dma_addr_t *reg_paddr);
|
||||||
void hif_dummy_mask_interrupt_call(struct hif_softc *hif_sc);
|
void hif_dummy_mask_interrupt_call(struct hif_softc *hif_sc);
|
||||||
|
void hif_dummy_display_stats(struct hif_softc *hif_ctx);
|
||||||
|
void hif_dummy_clear_stats(struct hif_softc *hif_ctx);
|
||||||
|
@@ -36,6 +36,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "htc_services.h"
|
#include "htc_services.h"
|
||||||
#include "a_types.h"
|
#include "a_types.h"
|
||||||
|
#include "dummy.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hif_intialize_default_ops() - intializes default operations values
|
* hif_intialize_default_ops() - intializes default operations values
|
||||||
*
|
*
|
||||||
@@ -49,6 +51,10 @@ static void hif_intialize_default_ops(struct hif_softc *hif_sc)
|
|||||||
bus_ops->hif_bus_close = NULL;
|
bus_ops->hif_bus_close = NULL;
|
||||||
|
|
||||||
/* dummy implementations */
|
/* dummy implementations */
|
||||||
|
bus_ops->hif_display_stats =
|
||||||
|
&hif_dummy_display_stats;
|
||||||
|
bus_ops->hif_clear_stats =
|
||||||
|
&hif_dummy_clear_stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUM_OPS (sizeof(struct hif_bus_ops) / sizeof(void *))
|
#define NUM_OPS (sizeof(struct hif_bus_ops) / sizeof(void *))
|
||||||
@@ -296,6 +302,20 @@ void hif_mask_interrupt_call(struct hif_opaque_softc *hif_hdl)
|
|||||||
hif_sc->bus_ops.hif_mask_interrupt_call(hif_sc);
|
hif_sc->bus_ops.hif_mask_interrupt_call(hif_sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hif_display_bus_stats(struct hif_opaque_softc *scn)
|
||||||
|
{
|
||||||
|
struct hif_softc *hif_sc = HIF_GET_SOFTC(scn);
|
||||||
|
|
||||||
|
hif_sc->bus_ops.hif_display_stats(hif_sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hif_clear_bus_stats(struct hif_opaque_softc *scn)
|
||||||
|
{
|
||||||
|
struct hif_softc *hif_sc = HIF_GET_SOFTC(scn);
|
||||||
|
|
||||||
|
hif_sc->bus_ops.hif_clear_stats(hif_sc);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hif_enable_power_management() - enable power management after driver load
|
* hif_enable_power_management() - enable power management after driver load
|
||||||
* @hif_hdl: opaque pointer to the hif context
|
* @hif_hdl: opaque pointer to the hif context
|
||||||
|
@@ -72,6 +72,8 @@ struct hif_bus_ops {
|
|||||||
void (*hif_enable_power_management)(struct hif_softc *hif_ctx,
|
void (*hif_enable_power_management)(struct hif_softc *hif_ctx,
|
||||||
bool is_packet_log_enabled);
|
bool is_packet_log_enabled);
|
||||||
void (*hif_disable_power_management)(struct hif_softc *hif_ctx);
|
void (*hif_disable_power_management)(struct hif_softc *hif_ctx);
|
||||||
|
void (*hif_display_stats)(struct hif_softc *hif_ctx);
|
||||||
|
void (*hif_clear_stats)(struct hif_softc *hif_ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HIF_SNOC
|
#ifdef HIF_SNOC
|
||||||
|
@@ -81,7 +81,10 @@ QDF_STATUS hif_initialize_pci_ops(struct hif_softc *hif_sc)
|
|||||||
&hif_pci_enable_power_management;
|
&hif_pci_enable_power_management;
|
||||||
bus_ops->hif_disable_power_management =
|
bus_ops->hif_disable_power_management =
|
||||||
&hif_pci_disable_power_management;
|
&hif_pci_disable_power_management;
|
||||||
|
bus_ops->hif_display_stats =
|
||||||
|
&hif_pci_display_stats;
|
||||||
|
bus_ops->hif_clear_stats =
|
||||||
|
&hif_pci_clear_stats;
|
||||||
|
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@@ -72,6 +72,10 @@ QDF_STATUS hif_initialize_snoc_ops(struct hif_bus_ops *bus_ops)
|
|||||||
&hif_dummy_enable_power_management;
|
&hif_dummy_enable_power_management;
|
||||||
bus_ops->hif_disable_power_management =
|
bus_ops->hif_disable_power_management =
|
||||||
&hif_dummy_disable_power_management;
|
&hif_dummy_disable_power_management;
|
||||||
|
bus_ops->hif_display_stats =
|
||||||
|
&hif_snoc_display_stats;
|
||||||
|
bus_ops->hif_clear_stats =
|
||||||
|
&hif_snoc_clear_stats;
|
||||||
|
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@@ -49,3 +49,5 @@ int hif_pci_dump_registers(struct hif_softc *scn);
|
|||||||
void hif_pci_enable_power_management(struct hif_softc *hif_ctx,
|
void hif_pci_enable_power_management(struct hif_softc *hif_ctx,
|
||||||
bool is_packet_log_enabled);
|
bool is_packet_log_enabled);
|
||||||
void hif_pci_disable_power_management(struct hif_softc *hif_ctx);
|
void hif_pci_disable_power_management(struct hif_softc *hif_ctx);
|
||||||
|
void hif_pci_display_stats(struct hif_softc *hif_ctx);
|
||||||
|
void hif_pci_clear_stats(struct hif_softc *hif_ctx);
|
||||||
|
@@ -41,3 +41,5 @@ int hif_snoc_bus_configure(struct hif_softc *scn);
|
|||||||
void hif_snoc_irq_disable(struct hif_softc *scn, int ce_id);
|
void hif_snoc_irq_disable(struct hif_softc *scn, int ce_id);
|
||||||
void hif_snoc_irq_enable(struct hif_softc *scn, int ce_id);
|
void hif_snoc_irq_enable(struct hif_softc *scn, int ce_id);
|
||||||
int hif_snoc_dump_registers(struct hif_softc *scn);
|
int hif_snoc_dump_registers(struct hif_softc *scn);
|
||||||
|
void hif_snoc_display_stats(struct hif_softc *hif_ctx);
|
||||||
|
void hif_snoc_clear_stats(struct hif_softc *hif_ctx);
|
||||||
|
@@ -489,6 +489,15 @@ void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type)
|
|||||||
HIF_INFO("%s: X", __func__);
|
HIF_INFO("%s: X", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hif_display_stats(struct hif_opaque_softc *hif_ctx)
|
||||||
|
{
|
||||||
|
hif_display_bus_stats(hif_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hif_clear_stats(struct hif_opaque_softc *hif_ctx)
|
||||||
|
{
|
||||||
|
hif_clear_bus_stats(hif_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hif_crash_shutdown_dump_bus_register() - dump bus registers
|
* hif_crash_shutdown_dump_bus_register() - dump bus registers
|
||||||
|
@@ -161,7 +161,8 @@ static inline bool hif_is_nss_wifi_enabled(struct hif_softc *sc)
|
|||||||
|
|
||||||
A_target_id_t hif_get_target_id(struct hif_softc *scn);
|
A_target_id_t hif_get_target_id(struct hif_softc *scn);
|
||||||
void hif_dump_pipe_debug_count(struct hif_softc *scn);
|
void hif_dump_pipe_debug_count(struct hif_softc *scn);
|
||||||
|
void hif_display_bus_stats(struct hif_opaque_softc *scn);
|
||||||
|
void hif_clear_bus_stats(struct hif_opaque_softc *scn);
|
||||||
bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count);
|
bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count);
|
||||||
void hif_shutdown_device(struct hif_opaque_softc *hif_ctx);
|
void hif_shutdown_device(struct hif_opaque_softc *hif_ctx);
|
||||||
int hif_bus_configure(struct hif_softc *scn);
|
int hif_bus_configure(struct hif_softc *scn);
|
||||||
|
@@ -1325,6 +1325,28 @@ void hif_pci_disable_power_management(struct hif_softc *hif_ctx)
|
|||||||
hif_pm_runtime_stop(pci_ctx);
|
hif_pm_runtime_stop(pci_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hif_pci_display_stats(struct hif_softc *hif_ctx)
|
||||||
|
{
|
||||||
|
struct hif_pci_softc *pci_ctx = HIF_GET_PCI_SOFTC(hif_ctx);
|
||||||
|
|
||||||
|
if (pci_ctx == NULL) {
|
||||||
|
HIF_ERROR("%s, hif_ctx null", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hif_display_ce_stats(&pci_ctx->ce_sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hif_pci_clear_stats(struct hif_softc *hif_ctx)
|
||||||
|
{
|
||||||
|
struct hif_pci_softc *pci_ctx = HIF_GET_PCI_SOFTC(hif_ctx);
|
||||||
|
|
||||||
|
if (pci_ctx == NULL) {
|
||||||
|
HIF_ERROR("%s, hif_ctx null", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hif_clear_ce_stats(&pci_ctx->ce_sc);
|
||||||
|
}
|
||||||
|
|
||||||
#define ATH_PCI_PROBE_RETRY_MAX 3
|
#define ATH_PCI_PROBE_RETRY_MAX 3
|
||||||
/**
|
/**
|
||||||
* hif_bus_open(): hif_bus_open
|
* hif_bus_open(): hif_bus_open
|
||||||
|
@@ -75,6 +75,28 @@ int hif_snoc_dump_registers(struct hif_softc *hif_ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hif_snoc_display_stats(struct hif_softc *hif_ctx)
|
||||||
|
{
|
||||||
|
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_ctx);
|
||||||
|
|
||||||
|
if (hif_state == NULL) {
|
||||||
|
HIF_ERROR("%s, hif_ctx null", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hif_display_ce_stats(hif_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hif_snoc_clear_stats(struct hif_softc *hif_ctx)
|
||||||
|
{
|
||||||
|
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_ctx);
|
||||||
|
|
||||||
|
if (hif_state == NULL) {
|
||||||
|
HIF_ERROR("%s, hif_ctx null", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hif_clear_ce_stats(hif_state);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hif_snoc_close(): hif_bus_close
|
* hif_snoc_close(): hif_bus_close
|
||||||
*
|
*
|
||||||
|
@@ -35,6 +35,12 @@
|
|||||||
|
|
||||||
#include <i_qdf_util.h>
|
#include <i_qdf_util.h>
|
||||||
|
|
||||||
|
#ifdef QCA_CONFIG_SMP
|
||||||
|
#define QDF_MAX_AVAILABLE_CPU 8
|
||||||
|
#else
|
||||||
|
#define QDF_MAX_AVAILABLE_CPU 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qdf_unlikely - Compiler-dependent macro denoting code likely to execute
|
* qdf_unlikely - Compiler-dependent macro denoting code likely to execute
|
||||||
* @_expr: expression to be checked
|
* @_expr: expression to be checked
|
||||||
@@ -409,4 +415,10 @@ static inline int qdf_get_pwr2(int value)
|
|||||||
return 1 << log2;
|
return 1 << log2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int qdf_get_cpu(void)
|
||||||
|
{
|
||||||
|
return __qdf_get_cpu();
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*_QDF_UTIL_H*/
|
#endif /*_QDF_UTIL_H*/
|
||||||
|
@@ -248,4 +248,27 @@ static inline bool __qdf_is_macaddr_equal(struct qdf_mac_addr *mac_addr1,
|
|||||||
#define __qdf_mb() mb()
|
#define __qdf_mb() mb()
|
||||||
|
|
||||||
#define __qdf_roundup(x, y) roundup(x, y)
|
#define __qdf_roundup(x, y) roundup(x, y)
|
||||||
|
|
||||||
|
#ifdef QCA_CONFIG_SMP
|
||||||
|
/**
|
||||||
|
* __qdf_get_cpu() - get cpu_index
|
||||||
|
*
|
||||||
|
* Return: cpu_index
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
int __qdf_get_cpu(void)
|
||||||
|
{
|
||||||
|
int cpu_index = get_cpu();
|
||||||
|
|
||||||
|
put_cpu();
|
||||||
|
return cpu_index;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline
|
||||||
|
int __qdf_get_cpu(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /*_I_QDF_UTIL_H*/
|
#endif /*_I_QDF_UTIL_H*/
|
||||||
|
Reference in New Issue
Block a user