Browse Source

qcacmn: Affine rx_err srng to all CPUs except 0

IPA and rx_err ring are processed in same CPU resulting
in low Tput.
To fix this, not allow processing of rx_err ring in
CPU 0

Change-Id: Id53a03c9290607beb1a595c84bfb0fd8d9f5d105
CRs-Fixed: 2949569
Ananya Gupta 4 years ago
parent
commit
f2851b458b

+ 7 - 0
dp/wifi3.0/dp_main.c

@@ -3138,6 +3138,7 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc)
 
 	int i = 0;
 	int num_irq = 0;
+	int rx_err_ring_intr_ctxt_id = HIF_MAX_GROUP;
 
 	qdf_mem_set(&soc->mon_intr_id_lmac_map,
 		    sizeof(soc->mon_intr_id_lmac_map), DP_MON_INVALID_LMAC_ID);
@@ -3225,9 +3226,15 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc)
 
 		hif_event_history_init(soc->hif_handle, i);
 		soc->intr_ctx[i].lro_ctx = qdf_lro_init();
+
+		if (rx_err_ring_mask)
+			rx_err_ring_intr_ctxt_id = i;
 	}
 
 	hif_configure_ext_group_interrupts(soc->hif_handle);
+	if (rx_err_ring_intr_ctxt_id != HIF_MAX_GROUP)
+		hif_config_irq_clear_cpu_affinity(soc->hif_handle,
+						  rx_err_ring_intr_ctxt_id, 0);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 19 - 0
hif/inc/hif.h

@@ -697,6 +697,25 @@ hif_needs_bmi(struct hif_opaque_softc *hif_ctx)
 }
 #endif /* WLAN_FEATURE_BMI */
 
+#ifdef HIF_CPU_CLEAR_AFFINITY
+/**
+ * hif_config_irq_clear_cpu_affinity() - Remove cpu affinity of IRQ
+ * @scn: HIF handle
+ * @intr_ctxt_id: interrupt group index
+ * @cpu: CPU core to clear
+ *
+ * Return: None
+ */
+void hif_config_irq_clear_cpu_affinity(struct hif_opaque_softc *scn,
+				       int intr_ctxt_id, int cpu);
+#else
+static inline
+void hif_config_irq_clear_cpu_affinity(struct hif_opaque_softc *scn,
+				       int intr_ctxt_id, int cpu)
+{
+}
+#endif
+
 /*
  * APIs to handle HIF specific diagnostic read accesses. These APIs are
  * synchronous and only allowed to be called from a context that

+ 13 - 0
hif/src/dispatcher/dummy.c

@@ -410,6 +410,19 @@ int hif_dummy_config_irq_by_ceid(struct hif_softc *scn, int ce_id)
 	return 0;
 }
 
+/**
+ * hif_config_irq_clear_affinity() - dummy call
+ * @scn: HIF handle
+ * @intr_ctxt_id: interrupt group index
+ * @cpu: CPU core to clear
+ *
+ * Return: None
+ */
+void hif_dummy_config_irq_clear_cpu_affinity(struct hif_softc *scn,
+					     int intr_ctxt_id, int cpu)
+{
+}
+
 /**
  * hif_dummy_log_bus_info - dummy call
  * @scn: hif context

+ 2 - 0
hif/src/dispatcher/dummy.h

@@ -93,3 +93,5 @@ bool hif_dummy_log_bus_info(struct hif_softc *scn, uint8_t *data,
 			    unsigned int *offset);
 int hif_dummy_enable_grp_irqs(struct hif_softc *scn);
 int hif_dummy_disable_grp_irqs(struct hif_softc *scn);
+void hif_dummy_config_irq_clear_cpu_affinity(struct hif_softc *scn,
+					     int intr_ctxt_id, int cpu);

+ 19 - 0
hif/src/dispatcher/ipci_api.h

@@ -270,6 +270,25 @@ int hif_ipci_enable_grp_irqs(struct hif_softc *scn);
 void hif_ipci_config_irq_affinity(struct hif_softc *scn);
 #endif
 
+#ifdef HIF_CPU_CLEAR_AFFINITY
+/**
+ * hif_ipci_config_irq_clear_cpu_affinity() - Remove cpu affinity of IRQ
+ * @scn: HIF handle
+ * @intr_ctxt_id: interrupt group index
+ * @cpu: CPU core to clear
+ *
+ * Return: None
+ */
+void hif_ipci_config_irq_clear_cpu_affinity(struct hif_softc *scn,
+					    int intr_ctxt_id, int cpu);
+#else
+static inline
+void hif_ipci_config_irq_clear_cpu_affinity(struct hif_softc *scn,
+					    int intr_ctxt_id, int cpu)
+{
+}
+#endif
+
 /**
  * hif_ipci_disable_grp_irqs(): disable grp IRQs
  * @scn: struct hif_softc

+ 15 - 0
hif/src/dispatcher/multibus.c

@@ -64,6 +64,8 @@ static void hif_initialize_default_ops(struct hif_softc *hif_sc)
 	bus_ops->hif_config_irq_by_ceid = &hif_dummy_config_irq_by_ceid;
 	bus_ops->hif_enable_grp_irqs = &hif_dummy_enable_grp_irqs;
 	bus_ops->hif_disable_grp_irqs = &hif_dummy_enable_grp_irqs;
+	bus_ops->hif_config_irq_clear_cpu_affinity =
+		&hif_dummy_config_irq_clear_cpu_affinity;
 }
 
 #define NUM_OPS (sizeof(struct hif_bus_ops) / sizeof(void *))
@@ -623,6 +625,19 @@ int hif_config_irq_by_ceid(struct hif_softc *hif_sc, int ce_id)
 	return hif_sc->bus_ops.hif_config_irq_by_ceid(hif_sc, ce_id);
 }
 
+#ifdef HIF_CPU_CLEAR_AFFINITY
+void hif_config_irq_clear_cpu_affinity(struct hif_opaque_softc *scn,
+				       int intr_ctxt_id, int cpu)
+{
+	struct hif_softc *hif_sc = HIF_GET_SOFTC(scn);
+
+	hif_sc->bus_ops.hif_config_irq_clear_cpu_affinity(hif_sc,
+							  intr_ctxt_id, cpu);
+}
+
+qdf_export_symbol(hif_config_irq_clear_affinity);
+#endif
+
 #ifdef HIF_BUS_LOG_INFO
 bool hif_log_bus_info(struct hif_softc *hif_sc, uint8_t *data,
 		      unsigned int *offset)

+ 2 - 0
hif/src/dispatcher/multibus.h

@@ -93,6 +93,8 @@ struct hif_bus_ops {
 	bool (*hif_needs_bmi)(struct hif_softc *hif_sc);
 	void (*hif_config_irq_affinity)(struct hif_softc *hif_sc);
 	int (*hif_config_irq_by_ceid)(struct hif_softc *hif_sc, int ce_id);
+	void (*hif_config_irq_clear_cpu_affinity)(struct hif_softc *hif_sc,
+						  int intr_ctxt_id, int cpu);
 	bool (*hif_log_bus_info)(struct hif_softc *scn, uint8_t *data,
 				 unsigned int *offset);
 	int (*hif_enable_grp_irqs)(struct hif_softc *scn);

+ 2 - 0
hif/src/dispatcher/multibus_ipci.c

@@ -86,6 +86,8 @@ QDF_STATUS hif_initialize_ipci_ops(struct hif_softc *hif_sc)
 		&hif_dummy_config_irq_affinity;
 #endif
 	bus_ops->hif_config_irq_by_ceid = &hif_dummy_config_irq_by_ceid;
+	bus_ops->hif_config_irq_clear_cpu_affinity =
+		&hif_ipci_config_irq_clear_cpu_affinity;
 	bus_ops->hif_log_bus_info = &hif_dummy_log_bus_info;
 	bus_ops->hif_enable_grp_irqs = hif_ipci_enable_grp_irqs;
 	bus_ops->hif_disable_grp_irqs = hif_ipci_disable_grp_irqs;

+ 2 - 0
hif/src/dispatcher/multibus_pci.c

@@ -95,6 +95,8 @@ QDF_STATUS hif_initialize_pci_ops(struct hif_softc *hif_sc)
 	bus_ops->hif_config_irq_affinity =
 		&hif_pci_config_irq_affinity;
 	bus_ops->hif_config_irq_by_ceid = &hif_ce_msi_configure_irq_by_ceid;
+	bus_ops->hif_config_irq_clear_cpu_affinity =
+		&hif_pci_config_irq_clear_cpu_affinity;
 	bus_ops->hif_log_bus_info = &hif_log_pcie_info;
 
 	return QDF_STATUS_SUCCESS;

+ 21 - 1
hif/src/hif_exec.h

@@ -106,7 +106,7 @@ struct hif_exec_context {
 	enum hif_exec_type type;
 	unsigned long long poll_start_time;
 	bool force_break;
-#ifdef HIF_CPU_PERF_AFFINE_MASK
+#if defined(HIF_CPU_PERF_AFFINE_MASK) || defined(HIF_CPU_CLEAR_AFFINITY)
 	/* Stores the affinity hint mask for each WLAN IRQ */
 	qdf_cpu_mask new_cpu_mask[HIF_MAX_GRP_IRQ];
 #endif
@@ -208,5 +208,25 @@ static inline void hif_ce_irq_remove_affinity_hint(int irq)
 {
 }
 #endif /* ifdef HIF_CPU_PERF_AFFINE_MASK */
+
+#ifdef HIF_CPU_CLEAR_AFFINITY
+/*
+ * hif_pci_config_irq_clear_affinity() - Remove cpu affinity of IRQ
+ * @scn: HIF handle
+ * @intr_ctxt: interrupt group index
+ * @cpu: CPU core to clear
+ *
+ * Return: None
+ */
+void hif_pci_config_irq_clear_cpu_affinity(struct hif_softc *scn,
+					   int intr_ctxt_id, int cpu);
+#else
+static inline
+void hif_pci_config_irq_clear_cpu_affinity(struct hif_softc *scn,
+					   int intr_ctxt_id, int cpu)
+{
+}
+#endif /* HIF_CPU_CLEAR_AFFINITY */
+
 #endif
 

+ 37 - 0
hif/src/ipcie/if_ipci.c

@@ -636,6 +636,43 @@ void hif_ipci_config_irq_affinity(struct hif_softc *scn)
 }
 #endif /* #ifdef HIF_CPU_PERF_AFFINE_MASK */
 
+#ifdef HIF_CPU_CLEAR_AFFINITY
+void hif_ipci_config_irq_clear_cpu_affinity(struct hif_softc *scn,
+					    int intr_ctxt_id, int cpu)
+{
+	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
+	struct hif_exec_context *hif_ext_group;
+	int i, ret;
+
+	if (intr_ctxt_id < hif_state->hif_num_extgroup) {
+		hif_ext_group = hif_state->hif_ext_group[intr_ctxt_id];
+		for (i = 0; i < hif_ext_group->numirq; i++) {
+			qdf_cpumask_setall(&hif_ext_group->new_cpu_mask[i]);
+			qdf_cpumask_clear_cpu(cpu,
+					      &hif_ext_group->new_cpu_mask[i]);
+			qdf_dev_modify_irq_status(hif_ext_group->os_irq[i],
+						  IRQ_NO_BALANCING, 0);
+			ret = qdf_dev_set_irq_affinity(hif_ext_group->os_irq[i],
+						       (struct qdf_cpu_mask *)
+						       &hif_ext_group->
+						       new_cpu_mask[i]);
+			qdf_dev_modify_irq_status(hif_ext_group->os_irq[i],
+						  0, IRQ_NO_BALANCING);
+			if (ret)
+				hif_err("Set affinity %*pbl fails for IRQ %d ",
+					qdf_cpumask_pr_args(&hif_ext_group->
+							    new_cpu_mask[i]),
+					hif_ext_group->os_irq[i]);
+			else
+				hif_debug("Set affinity %*pbl for IRQ: %d",
+					  qdf_cpumask_pr_args(&hif_ext_group->
+							      new_cpu_mask[i]),
+					  hif_ext_group->os_irq[0]);
+		}
+	}
+}
+#endif
+
 int hif_ipci_configure_grp_irq(struct hif_softc *scn,
 			       struct hif_exec_context *hif_ext_group)
 {

+ 38 - 0
hif/src/pcie/if_pci.c

@@ -3061,6 +3061,44 @@ void hif_pci_ce_irq_set_affinity_hint(
 }
 #endif /* #ifdef HIF_CPU_PERF_AFFINE_MASK */
 
+#ifdef HIF_CPU_CLEAR_AFFINITY
+void hif_pci_config_irq_clear_cpu_affinity(struct hif_softc *scn,
+					   int intr_ctxt_id, int cpu)
+{
+	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
+	struct hif_exec_context *hif_ext_group;
+	int i, ret;
+
+	if (intr_ctxt_id < hif_state->hif_num_extgroup) {
+		hif_ext_group = hif_state->hif_ext_group[intr_ctxt_id];
+
+		for (i = 0; i < hif_ext_group->numirq; i++) {
+			qdf_cpumask_setall(&hif_ext_group->new_cpu_mask[i]);
+			qdf_cpumask_clear_cpu(cpu,
+					      &hif_ext_group->new_cpu_mask[i]);
+			qdf_dev_modify_irq_status(hif_ext_group->os_irq[i],
+						  IRQ_NO_BALANCING, 0);
+			ret = qdf_dev_set_irq_affinity(hif_ext_group->os_irq[i],
+						       (struct qdf_cpu_mask *)
+						       &hif_ext_group->
+						       new_cpu_mask[i]);
+			qdf_dev_modify_irq_status(hif_ext_group->os_irq[i],
+						  0, IRQ_NO_BALANCING);
+			if (ret)
+				hif_err("Set affinity %*pbl fails for IRQ %d ",
+					qdf_cpumask_pr_args(&hif_ext_group->
+							    new_cpu_mask[i]),
+					hif_ext_group->os_irq[i]);
+			else
+				hif_debug("Set affinity %*pbl for IRQ: %d",
+					  qdf_cpumask_pr_args(&hif_ext_group->
+							      new_cpu_mask[i]),
+					  hif_ext_group->os_irq[i]);
+		}
+	}
+}
+#endif
+
 void hif_pci_config_irq_affinity(struct hif_softc *scn)
 {
 	int i;

+ 10 - 1
qdf/inc/qdf_threads.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -169,6 +169,15 @@ void qdf_cpumask_set_cpu(unsigned int cpu, qdf_cpu_mask *dstp);
  */
 void qdf_cpumask_setall(qdf_cpu_mask *dstp);
 
+/**
+ * qdf_cpumask_clear_cpu() - clear a cpu in a cpumask
+ * @cpu: cpu number
+ * @dstp: cpumask pointer
+ *
+ * Return: None
+ */
+void qdf_cpumask_clear_cpu(unsigned int cpu, qdf_cpu_mask *dstp);
+
 /**
  * qdf_cpumask_empty - Check if cpu_mask is empty
  * @srcp: cpumask pointer

+ 7 - 1
qdf/linux/src/qdf_threads.c

@@ -272,9 +272,15 @@ void qdf_cpumask_set_cpu(unsigned int cpu, qdf_cpu_mask *dstp)
 {
 	cpumask_set_cpu(cpu, dstp);
 }
-
 qdf_export_symbol(qdf_cpumask_set_cpu);
 
+void qdf_cpumask_clear_cpu(unsigned int cpu, qdf_cpu_mask *dstp)
+{
+	cpumask_clear_cpu(cpu, dstp);
+}
+
+qdf_export_symbol(qdf_cpumask_clear_cpu);
+
 void qdf_cpumask_setall(qdf_cpu_mask *dstp)
 {
 	cpumask_setall(dstp);