]> git.karo-electronics.de Git - linux-beck.git/commitdiff
mpt2sas, mpt3sas: set cpu affinity for each MSIX vectors
authorSreekanth Reddy <sreekanth.reddy@avagotech.com>
Mon, 12 Jan 2015 06:09:03 +0000 (11:39 +0530)
committerChristoph Hellwig <hch@lst.de>
Tue, 13 Jan 2015 15:27:28 +0000 (16:27 +0100)
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>
drivers/scsi/mpt2sas/mpt2sas_base.c
drivers/scsi/mpt2sas/mpt2sas_base.h
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/mpt3sas/mpt3sas_base.h

index ee8ba5c18d6dcf1b74631900f1070a5a1fed831c..11248de92b3b16cdc751c3578ef6653f169dc825 100644 (file)
@@ -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);
+       }
 }
 
 /**
index 72bffec60303d2b2be9e98fa4848f04e15b50b83..46e8d517f743b486b5428ee71ac1f229ec035ce9 100644 (file)
@@ -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;
 };
 
index 549b50031d7ebca01bbbac5931f37613a13448b5..14a781b6b88dad852a40311f86e2b58e0e2a7785 100644 (file)
@@ -1584,6 +1584,8 @@ _base_free_irq(struct MPT3SAS_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);
@@ -1613,6 +1615,11 @@ _base_request_irq(struct MPT3SAS_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",
@@ -1647,6 +1654,7 @@ static void
 _base_assign_reply_queues(struct MPT3SAS_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;
@@ -1661,20 +1669,30 @@ _base_assign_reply_queues(struct MPT3SAS_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(MPT3SAS_FMT
+                           "error setting affinity hint for irq vector %d\n",
+                           ioc->name, reply_q->vector));
                index++;
-
-       } while (cpu < nr_cpus);
+       }
 }
 
 /**
index 7e9f55baa1bca136fb7f163f3a70094668f2d372..afa881682bef4d489a5f5e6a1f67a85dd5688b88 100644 (file)
@@ -507,6 +507,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;
 };