diff options
author | Quinn Tran <quinn.tran@qlogic.com> | 2015-12-17 14:57:05 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2016-01-07 16:57:46 -0500 |
commit | cdb898c52d1dfad4b4800b83a58b3fe5d352edde (patch) | |
tree | a75040b860ca23bf650979950ca5c467e7c8670b /drivers/scsi/qla2xxx/qla_isr.c | |
parent | 7560151b6b3c1f4432c1c5b5b6496070d1f38484 (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.c | 76 |
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 *); | |||
18 | static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *); | 18 | static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *); |
19 | static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, | 19 | static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, |
20 | sts_entry_t *); | 20 | sts_entry_t *); |
21 | static void qla_irq_affinity_notify(struct irq_affinity_notify *, | ||
22 | const cpumask_t *); | ||
23 | static 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 */ | ||
3276 | static 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 | |||
3305 | void 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 | } | ||