diff options
| author | Mohit Khanna <mkhannaqca@codeaurora.org> | 2017-01-19 21:15:35 -0800 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2017-01-26 18:59:55 -0800 |
| commit | bfe57ac2e249d384254bf46fe5574c0f9224c720 (patch) | |
| tree | 0abe4a97e8b2b57912602c6ef8a82d377d0eb11e /hif/src | |
| parent | 59e53adca11a786cfd12c7b3e51e48865e29d6ab (diff) | |
qcacmn: modify HIF NAPI blacklist mechanism
The existing HIF NAPI blacklist feature uses irq_blacklist_on(off) APIs
which make a call to the userspace irq_balancer.
Replace these APIs with kernel API irq_modify_status to mark (or unmark) the
individual interrupts with IRQ_NO_BALANCING flag. Once marked, the
msm-irq-balancer will not be able to move the CE interrupts around.
Change-Id: I4d780fa8780b42a668006e13a49eb1299304e633
CRs-Fixed: 1114161
Diffstat (limited to 'hif/src')
| -rw-r--r-- | hif/src/hif_napi.c | 95 |
1 files changed, 70 insertions, 25 deletions
diff --git a/hif/src/hif_napi.c b/hif/src/hif_napi.c index 2209b2bd9a7b..46b87e5e89d4 100644 --- a/hif/src/hif_napi.c +++ b/hif/src/hif_napi.c @@ -39,6 +39,7 @@ #include <linux/cpu.h> #include <linux/topology.h> #include <linux/interrupt.h> +#include <linux/irq.h> #ifdef HELIUMPLUS #include <soc/qcom/irq-helper.h> #include <linux/sched/core_ctl.h> @@ -76,7 +77,8 @@ static int hif_napi_cpu_migrate(struct qca_napi_data *napid, int cpu, return 0; } -int hif_napi_cpu_blacklist(uint8_t flags, enum qca_blacklist_op op) +int hif_napi_cpu_blacklist(struct qca_napi_data *napid, + enum qca_blacklist_op op) { return 0; } @@ -597,22 +599,21 @@ int hif_napi_event(struct hif_opaque_softc *hif_ctx, enum qca_napi_event event, }; /* switch */ - qdf_spin_unlock_bh(&(napid->lock)); - - /* Call this API without spin_locks hif_napi_cpu_blacklist */ switch (blacklist_pending) { case BLACKLIST_ON_PENDING: /* assume the control of WLAN IRQs */ - hif_napi_cpu_blacklist(napid->flags, BLACKLIST_ON); + hif_napi_cpu_blacklist(napid, BLACKLIST_ON); break; case BLACKLIST_OFF_PENDING: /* yield the control of WLAN IRQs */ - hif_napi_cpu_blacklist(napid->flags, BLACKLIST_OFF); + hif_napi_cpu_blacklist(napid, BLACKLIST_OFF); break; default: /* nothing to do */ break; } /* switch blacklist_pending */ + qdf_spin_unlock_bh(&(napid->lock)); + if (prev_state != napid->state) { if (napid->state == ENABLE_NAPI_MASK) { rc = 1; @@ -727,15 +728,19 @@ bool hif_napi_correct_cpu(struct qca_napi_info *napi_info) if (napid->flags & QCA_NAPI_FEATURE_CPU_CORRECTION) { cpu = qdf_get_cpu(); - if (unlikely((hif_napi_cpu_blacklist(napid->flags, + if (unlikely((hif_napi_cpu_blacklist(napid, BLACKLIST_QUERY) > 0) && (cpu != napi_info->cpu))) { right_cpu = false; NAPI_DEBUG("interrupt on wrong CPU, correcting"); cpumask.bits[0] = (0x01 << napi_info->cpu); + + irq_modify_status(napi_info->irq, IRQ_NO_BALANCING, 0); rc = irq_set_affinity_hint(napi_info->irq, &cpumask); + irq_modify_status(napi_info->irq, 0, IRQ_NO_BALANCING); + if (rc) HIF_ERROR("error setting irq affinity hint: %d", rc); else @@ -903,9 +908,10 @@ void hif_napi_update_yield_stats(struct CE_state *ce_state, return; } else { napi_data = &(hif->napi_data); - if (unlikely(NULL == napi_data)) + if (unlikely(NULL == napi_data)) { QDF_ASSERT(NULL != napi_data); - return; + return; + } } ce_id = ce_state->id; @@ -1326,6 +1332,8 @@ static int hncm_migrate_to(struct qca_napi_data *napid, NAPI_DEBUG("-->%s(napi_cd=%d, didx=%d)", __func__, napi_ce, didx); cpumask.bits[0] = (1 << didx); + + irq_modify_status(napid->napis[napi_ce].irq, IRQ_NO_BALANCING, 0); rc = irq_set_affinity_hint(napid->napis[napi_ce].irq, &cpumask); /* unmark the napis bitmap in the cpu table */ @@ -1483,20 +1491,56 @@ hncm_return: return rc; } + +/** + * hif_napi_bl_irq() - calls irq_modify_status to enable/disable blacklisting + * @napid: pointer to qca_napi_data structure + * @bl_flag: blacklist flag to enable/disable blacklisting + * + * The function enables/disables blacklisting for all the copy engine + * interrupts on which NAPI is enabled. + * + * Return: None + */ +static inline void hif_napi_bl_irq(struct qca_napi_data *napid, bool bl_flag) +{ + int i; + for (i = 0; i < CE_COUNT_MAX; i++) { + /* check if NAPI is enabled on the CE */ + if (!(napid->ce_map & (0x01 << i))) + continue; + + if (bl_flag == true) + irq_modify_status(napid->napis[i].irq, + 0, IRQ_NO_BALANCING); + else + irq_modify_status(napid->napis[i].irq, + IRQ_NO_BALANCING, 0); + HIF_INFO("%s: bl_flag %d CE %d", __func__, bl_flag, i); + } +} + /** - * hif_napi_cpu_blacklist() - calls kernel API to enable/disable blacklisting - * @flags: NAPI feature flags + * hif_napi_cpu_blacklist() - en(dis)ables blacklisting for NAPI RX interrupts. + * @napid: pointer to qca_napi_data structure * @op: blacklist operation to perform * + * The function enables/disables/queries blacklisting for all CE RX + * interrupts with NAPI enabled. Besides blacklisting, it also enables/disables + * core_ctl_set_boost. + * Once blacklisting is enabled, the interrupts will not be managed by the IRQ + * balancer. + * * Return: -EINVAL, in case IRQ_BLACKLISTING and CORE_CTL_BOOST is not enabled * for BLACKLIST_QUERY op - blacklist refcount - * for BLACKLIST_ON op - return value from kernel blacklist API - * for BLACKLIST_OFF op - return value from kernel blacklist API + * for BLACKLIST_ON op - return value from core_ctl_set_boost API + * for BLACKLIST_OFF op - return value from core_ctl_set_boost API */ -int hif_napi_cpu_blacklist(uint8_t flags, enum qca_blacklist_op op) +int hif_napi_cpu_blacklist(struct qca_napi_data *napid, enum qca_blacklist_op op) { int rc = 0; static int ref_count; /* = 0 by the compiler */ + uint8_t flags = napid->flags; bool bl_en = flags & QCA_NAPI_FEATURE_IRQ_BLACKLISTING; bool ccb_en = flags & QCA_NAPI_FEATURE_CORE_CTL_BOOST; @@ -1513,22 +1557,23 @@ int hif_napi_cpu_blacklist(uint8_t flags, enum qca_blacklist_op op) break; case BLACKLIST_ON: ref_count++; - rc = irq_blacklist_on(); - NAPI_DEBUG("blacklist_on() returns %d", rc); - - rc = core_ctl_set_boost(true); - NAPI_DEBUG("boost_on() returns %d - refcnt=%d", rc, ref_count); + rc = 0; + if (ref_count == 1) { + rc = core_ctl_set_boost(true); + NAPI_DEBUG("boost_on() returns %d - refcnt=%d", + rc, ref_count); + hif_napi_bl_irq(napid, true); + } break; - case BLACKLIST_OFF: - while (ref_count > 0) { - rc = irq_blacklist_off(); - NAPI_DEBUG("blacklist_off() returns %d", rc); - + if (ref_count) + ref_count--; + rc = 0; + if (ref_count == 0) { rc = core_ctl_set_boost(false); NAPI_DEBUG("boost_off() returns %d - refcnt=%d", rc, ref_count); - ref_count--; + hif_napi_bl_irq(napid, false); } break; default: |
