diff options
author | Sreekanth Reddy <sreekanth.reddy@avagotech.com> | 2015-01-12 09:09:03 +0300 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2015-01-13 18:27:28 +0300 |
commit | 14b3114d940cdc4fea8afdab8e23508361db027f (patch) | |
tree | 836a81b64136e75dbd002ea13e425928b9835b95 /drivers/scsi/mpt2sas | |
parent | a03bd153b1b31c24b00d516bdbf9370ab8132650 (diff) | |
download | linux-14b3114d940cdc4fea8afdab8e23508361db027f.tar.xz |
mpt2sas, mpt3sas: set cpu affinity for each MSIX vectors
Added a support to set cpu affinity mask for each MSIX vector enabled
by the HBA. So that, running the irqbalancer will balance interrupts among
the cpus.
Change_set:
1. Added affinity_hint varable of type cpumask_var_t in adapter_reply_queue
structure. And allocated a memory for this varable by calling
alloc_cpumask_var.
2. Call the API irq_set_affinity_hint for each MSIx vector to affiniate it
with calculated cpus at driver inilization time.
3. While freeing the MSIX vector, call this same API to release the cpu
affinity mask for each MSIx vector by providing the NULL value in
cpumask argument.
4. then call the free_cpumask_var API to free the memory allocated in step 2.
Signed-off-by: Sreekanth Reddy <Sreekanth.Reddy@avagotech.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 24 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 1 |
2 files changed, 22 insertions, 3 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index ee8ba5c18d6d..11248de92b3b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -1300,6 +1300,8 @@ _base_free_irq(struct MPT2SAS_ADAPTER *ioc) list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { list_del(&reply_q->list); + irq_set_affinity_hint(reply_q->vector, NULL); + free_cpumask_var(reply_q->affinity_hint); synchronize_irq(reply_q->vector); free_irq(reply_q->vector, reply_q); kfree(reply_q); @@ -1329,6 +1331,11 @@ _base_request_irq(struct MPT2SAS_ADAPTER *ioc, u8 index, u32 vector) reply_q->ioc = ioc; reply_q->msix_index = index; reply_q->vector = vector; + + if (!alloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL)) + return -ENOMEM; + cpumask_clear(reply_q->affinity_hint); + atomic_set(&reply_q->busy, 0); if (ioc->msix_enable) snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", @@ -1363,6 +1370,7 @@ static void _base_assign_reply_queues(struct MPT2SAS_ADAPTER *ioc) { unsigned int cpu, nr_cpus, nr_msix, index = 0; + struct adapter_reply_queue *reply_q; if (!_base_is_controller_msix_enabled(ioc)) return; @@ -1377,20 +1385,30 @@ _base_assign_reply_queues(struct MPT2SAS_ADAPTER *ioc) cpu = cpumask_first(cpu_online_mask); - do { + list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { + unsigned int i, group = nr_cpus / nr_msix; + if (cpu >= nr_cpus) + break; + if (index < nr_cpus % nr_msix) group++; for (i = 0 ; i < group ; i++) { ioc->cpu_msix_table[cpu] = index; + cpumask_or(reply_q->affinity_hint, + reply_q->affinity_hint, get_cpu_mask(cpu)); cpu = cpumask_next(cpu, cpu_online_mask); } + if (irq_set_affinity_hint(reply_q->vector, + reply_q->affinity_hint)) + dinitprintk(ioc, pr_info(MPT2SAS_FMT + "error setting affinity hint for irq vector %d\n", + ioc->name, reply_q->vector)); index++; - - } while (cpu < nr_cpus); + } } /** diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 72bffec60303..46e8d517f743 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h @@ -587,6 +587,7 @@ struct adapter_reply_queue { Mpi2ReplyDescriptorsUnion_t *reply_post_free; char name[MPT_NAME_LENGTH]; atomic_t busy; + cpumask_var_t affinity_hint; struct list_head list; }; |