aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_isr.c
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 /drivers/scsi/qla2xxx/qla_isr.c
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>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c76
1 files changed, 75 insertions, 1 deletions
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}