aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuinn Tran <quinn.tran@qlogic.com>2015-12-17 14:57:05 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2016-01-07 16:57:46 -0500
commitcdb898c52d1dfad4b4800b83a58b3fe5d352edde (patch)
treea75040b860ca23bf650979950ca5c467e7c8670b
parent7560151b6b3c1f4432c1c5b5b6496070d1f38484 (diff)
qla2xxx: Add irq affinity notification
Register to receive notification of when irq setting change occured. Signed-off-by: Quinn Tran <quinn.tran@qlogic.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c76
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c12
3 files changed, 93 insertions, 1 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 216a944c1ca5..c4fc32e9aaf9 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2714,11 +2714,16 @@ struct isp_operations {
2714 2714
2715struct scsi_qla_host; 2715struct scsi_qla_host;
2716 2716
2717
2718#define QLA83XX_RSPQ_MSIX_ENTRY_NUMBER 1 /* refer to qla83xx_msix_entries */
2719
2717struct qla_msix_entry { 2720struct qla_msix_entry {
2718 int have_irq; 2721 int have_irq;
2719 uint32_t vector; 2722 uint32_t vector;
2720 uint16_t entry; 2723 uint16_t entry;
2721 struct rsp_que *rsp; 2724 struct rsp_que *rsp;
2725 struct irq_affinity_notify irq_notify;
2726 int cpuid;
2722}; 2727};
2723 2728
2724#define WATCH_INTERVAL 1 /* number of seconds */ 2729#define WATCH_INTERVAL 1 /* number of seconds */
@@ -2930,6 +2935,7 @@ struct qlt_hw_data {
2930 spinlock_t q_full_lock; 2935 spinlock_t q_full_lock;
2931 uint32_t leak_exchg_thresh_hold; 2936 uint32_t leak_exchg_thresh_hold;
2932 spinlock_t sess_lock; 2937 spinlock_t sess_lock;
2938 int rspq_vector_cpuid;
2933}; 2939};
2934 2940
2935#define MAX_QFULL_CMDS_ALLOC 8192 2941#define MAX_QFULL_CMDS_ALLOC 8192
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index ea7e8e8a065a..cf0fe8ec12c7 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -18,6 +18,10 @@ static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
18static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *); 18static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
19static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, 19static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
20 sts_entry_t *); 20 sts_entry_t *);
21static void qla_irq_affinity_notify(struct irq_affinity_notify *,
22 const cpumask_t *);
23static void qla_irq_affinity_release(struct kref *);
24
21 25
22/** 26/**
23 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. 27 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
@@ -2548,6 +2552,14 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
2548 if (!vha->flags.online) 2552 if (!vha->flags.online)
2549 return; 2553 return;
2550 2554
2555 if (rsp->msix->cpuid != smp_processor_id()) {
2556 /* if kernel does not notify qla of IRQ's CPU change,
2557 * then set it here.
2558 */
2559 rsp->msix->cpuid = smp_processor_id();
2560 ha->tgt.rspq_vector_cpuid = rsp->msix->cpuid;
2561 }
2562
2551 while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { 2563 while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
2552 pkt = (struct sts_entry_24xx *)rsp->ring_ptr; 2564 pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
2553 2565
@@ -2979,8 +2991,11 @@ qla24xx_disable_msix(struct qla_hw_data *ha)
2979 2991
2980 for (i = 0; i < ha->msix_count; i++) { 2992 for (i = 0; i < ha->msix_count; i++) {
2981 qentry = &ha->msix_entries[i]; 2993 qentry = &ha->msix_entries[i];
2982 if (qentry->have_irq) 2994 if (qentry->have_irq) {
2995 /* un-register irq cpu affinity notification */
2996 irq_set_affinity_notifier(qentry->vector, NULL);
2983 free_irq(qentry->vector, qentry->rsp); 2997 free_irq(qentry->vector, qentry->rsp);
2998 }
2984 } 2999 }
2985 pci_disable_msix(ha->pdev); 3000 pci_disable_msix(ha->pdev);
2986 kfree(ha->msix_entries); 3001 kfree(ha->msix_entries);
@@ -3043,6 +3058,9 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
3043 qentry->entry = entries[i].entry; 3058 qentry->entry = entries[i].entry;
3044 qentry->have_irq = 0; 3059 qentry->have_irq = 0;
3045 qentry->rsp = NULL; 3060 qentry->rsp = NULL;
3061 qentry->irq_notify.notify = qla_irq_affinity_notify;
3062 qentry->irq_notify.release = qla_irq_affinity_release;
3063 qentry->cpuid = -1;
3046 } 3064 }
3047 3065
3048 /* Enable MSI-X vectors for the base queue */ 3066 /* Enable MSI-X vectors for the base queue */
@@ -3061,6 +3079,18 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
3061 qentry->have_irq = 1; 3079 qentry->have_irq = 1;
3062 qentry->rsp = rsp; 3080 qentry->rsp = rsp;
3063 rsp->msix = qentry; 3081 rsp->msix = qentry;
3082
3083 /* Register for CPU affinity notification. */
3084 irq_set_affinity_notifier(qentry->vector, &qentry->irq_notify);
3085
3086 /* Schedule work (ie. trigger a notification) to read cpu
3087 * mask for this specific irq.
3088 * kref_get is required because
3089 * irq_affinity_notify() will do
3090 * kref_put().
3091 */
3092 kref_get(&qentry->irq_notify.kref);
3093 schedule_work(&qentry->irq_notify.work);
3064 } 3094 }
3065 3095
3066 /* 3096 /*
@@ -3240,3 +3270,47 @@ int qla25xx_request_irq(struct rsp_que *rsp)
3240 msix->rsp = rsp; 3270 msix->rsp = rsp;
3241 return ret; 3271 return ret;
3242} 3272}
3273
3274
3275/* irq_set_affinity/irqbalance will trigger notification of cpu mask update */
3276static void qla_irq_affinity_notify(struct irq_affinity_notify *notify,
3277 const cpumask_t *mask)
3278{
3279 struct qla_msix_entry *e =
3280 container_of(notify, struct qla_msix_entry, irq_notify);
3281 struct qla_hw_data *ha;
3282 struct scsi_qla_host *base_vha;
3283
3284 /* user is recommended to set mask to just 1 cpu */
3285 e->cpuid = cpumask_first(mask);
3286
3287 ha = e->rsp->hw;
3288 base_vha = pci_get_drvdata(ha->pdev);
3289
3290 ql_dbg(ql_dbg_init, base_vha, 0xffff,
3291 "%s: host %ld : vector %d cpu %d \n", __func__,
3292 base_vha->host_no, e->vector, e->cpuid);
3293
3294 if (e->have_irq) {
3295 if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) &&
3296 (e->entry == QLA83XX_RSPQ_MSIX_ENTRY_NUMBER)) {
3297 ha->tgt.rspq_vector_cpuid = e->cpuid;
3298 ql_dbg(ql_dbg_init, base_vha, 0xffff,
3299 "%s: host%ld: rspq vector %d cpu %d runtime change\n",
3300 __func__, base_vha->host_no, e->vector, e->cpuid);
3301 }
3302 }
3303}
3304
3305void qla_irq_affinity_release(struct kref *ref)
3306{
3307 struct irq_affinity_notify *notify =
3308 container_of(ref, struct irq_affinity_notify, kref);
3309 struct qla_msix_entry *e =
3310 container_of(notify, struct qla_msix_entry, irq_notify);
3311 struct scsi_qla_host *base_vha = pci_get_drvdata(e->rsp->hw->pdev);
3312
3313 ql_dbg(ql_dbg_init, base_vha, 0xffff,
3314 "%s: host%ld: vector %d cpu %d \n", __func__,
3315 base_vha->host_no, e->vector, e->cpuid);
3316}
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 6136987df164..9a4aed0e8241 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -6232,6 +6232,7 @@ qlt_enable_vha(struct scsi_qla_host *vha)
6232 struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 6232 struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
6233 unsigned long flags; 6233 unsigned long flags;
6234 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 6234 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
6235 int rspq_ent = QLA83XX_RSPQ_MSIX_ENTRY_NUMBER;
6235 6236
6236 if (!tgt) { 6237 if (!tgt) {
6237 ql_dbg(ql_dbg_tgt, vha, 0xe069, 6238 ql_dbg(ql_dbg_tgt, vha, 0xe069,
@@ -6250,6 +6251,17 @@ qlt_enable_vha(struct scsi_qla_host *vha)
6250 qla24xx_disable_vp(vha); 6251 qla24xx_disable_vp(vha);
6251 qla24xx_enable_vp(vha); 6252 qla24xx_enable_vp(vha);
6252 } else { 6253 } else {
6254 if (ha->msix_entries) {
6255 ql_dbg(ql_dbg_tgt, vha, 0xffff,
6256 "%s: host%ld : vector %d cpu %d\n",
6257 __func__, vha->host_no,
6258 ha->msix_entries[rspq_ent].vector,
6259 ha->msix_entries[rspq_ent].cpuid);
6260
6261 ha->tgt.rspq_vector_cpuid =
6262 ha->msix_entries[rspq_ent].cpuid;
6263 }
6264
6253 set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); 6265 set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
6254 qla2xxx_wake_dpc(base_vha); 6266 qla2xxx_wake_dpc(base_vha);
6255 qla2x00_wait_for_hba_online(base_vha); 6267 qla2x00_wait_for_hba_online(base_vha);