aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSreekanth Reddy <sreekanth.reddy@avagotech.com>2015-01-12 01:09:03 -0500
committerChristoph Hellwig <hch@lst.de>2015-01-13 10:27:28 -0500
commit14b3114d940cdc4fea8afdab8e23508361db027f (patch)
tree836a81b64136e75dbd002ea13e425928b9835b95
parenta03bd153b1b31c24b00d516bdbf9370ab8132650 (diff)
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>
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c24
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h1
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.c24
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.h1
4 files changed, 44 insertions, 6 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)
1300 1300
1301 list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { 1301 list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) {
1302 list_del(&reply_q->list); 1302 list_del(&reply_q->list);
1303 irq_set_affinity_hint(reply_q->vector, NULL);
1304 free_cpumask_var(reply_q->affinity_hint);
1303 synchronize_irq(reply_q->vector); 1305 synchronize_irq(reply_q->vector);
1304 free_irq(reply_q->vector, reply_q); 1306 free_irq(reply_q->vector, reply_q);
1305 kfree(reply_q); 1307 kfree(reply_q);
@@ -1329,6 +1331,11 @@ _base_request_irq(struct MPT2SAS_ADAPTER *ioc, u8 index, u32 vector)
1329 reply_q->ioc = ioc; 1331 reply_q->ioc = ioc;
1330 reply_q->msix_index = index; 1332 reply_q->msix_index = index;
1331 reply_q->vector = vector; 1333 reply_q->vector = vector;
1334
1335 if (!alloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL))
1336 return -ENOMEM;
1337 cpumask_clear(reply_q->affinity_hint);
1338
1332 atomic_set(&reply_q->busy, 0); 1339 atomic_set(&reply_q->busy, 0);
1333 if (ioc->msix_enable) 1340 if (ioc->msix_enable)
1334 snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", 1341 snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d",
@@ -1363,6 +1370,7 @@ static void
1363_base_assign_reply_queues(struct MPT2SAS_ADAPTER *ioc) 1370_base_assign_reply_queues(struct MPT2SAS_ADAPTER *ioc)
1364{ 1371{
1365 unsigned int cpu, nr_cpus, nr_msix, index = 0; 1372 unsigned int cpu, nr_cpus, nr_msix, index = 0;
1373 struct adapter_reply_queue *reply_q;
1366 1374
1367 if (!_base_is_controller_msix_enabled(ioc)) 1375 if (!_base_is_controller_msix_enabled(ioc))
1368 return; 1376 return;
@@ -1377,20 +1385,30 @@ _base_assign_reply_queues(struct MPT2SAS_ADAPTER *ioc)
1377 1385
1378 cpu = cpumask_first(cpu_online_mask); 1386 cpu = cpumask_first(cpu_online_mask);
1379 1387
1380 do { 1388 list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
1389
1381 unsigned int i, group = nr_cpus / nr_msix; 1390 unsigned int i, group = nr_cpus / nr_msix;
1382 1391
1392 if (cpu >= nr_cpus)
1393 break;
1394
1383 if (index < nr_cpus % nr_msix) 1395 if (index < nr_cpus % nr_msix)
1384 group++; 1396 group++;
1385 1397
1386 for (i = 0 ; i < group ; i++) { 1398 for (i = 0 ; i < group ; i++) {
1387 ioc->cpu_msix_table[cpu] = index; 1399 ioc->cpu_msix_table[cpu] = index;
1400 cpumask_or(reply_q->affinity_hint,
1401 reply_q->affinity_hint, get_cpu_mask(cpu));
1388 cpu = cpumask_next(cpu, cpu_online_mask); 1402 cpu = cpumask_next(cpu, cpu_online_mask);
1389 } 1403 }
1390 1404
1405 if (irq_set_affinity_hint(reply_q->vector,
1406 reply_q->affinity_hint))
1407 dinitprintk(ioc, pr_info(MPT2SAS_FMT
1408 "error setting affinity hint for irq vector %d\n",
1409 ioc->name, reply_q->vector));
1391 index++; 1410 index++;
1392 1411 }
1393 } while (cpu < nr_cpus);
1394} 1412}
1395 1413
1396/** 1414/**
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 {
587 Mpi2ReplyDescriptorsUnion_t *reply_post_free; 587 Mpi2ReplyDescriptorsUnion_t *reply_post_free;
588 char name[MPT_NAME_LENGTH]; 588 char name[MPT_NAME_LENGTH];
589 atomic_t busy; 589 atomic_t busy;
590 cpumask_var_t affinity_hint;
590 struct list_head list; 591 struct list_head list;
591}; 592};
592 593
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 549b50031d7e..14a781b6b88d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1584,6 +1584,8 @@ _base_free_irq(struct MPT3SAS_ADAPTER *ioc)
1584 1584
1585 list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { 1585 list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) {
1586 list_del(&reply_q->list); 1586 list_del(&reply_q->list);
1587 irq_set_affinity_hint(reply_q->vector, NULL);
1588 free_cpumask_var(reply_q->affinity_hint);
1587 synchronize_irq(reply_q->vector); 1589 synchronize_irq(reply_q->vector);
1588 free_irq(reply_q->vector, reply_q); 1590 free_irq(reply_q->vector, reply_q);
1589 kfree(reply_q); 1591 kfree(reply_q);
@@ -1613,6 +1615,11 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index, u32 vector)
1613 reply_q->ioc = ioc; 1615 reply_q->ioc = ioc;
1614 reply_q->msix_index = index; 1616 reply_q->msix_index = index;
1615 reply_q->vector = vector; 1617 reply_q->vector = vector;
1618
1619 if (!alloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL))
1620 return -ENOMEM;
1621 cpumask_clear(reply_q->affinity_hint);
1622
1616 atomic_set(&reply_q->busy, 0); 1623 atomic_set(&reply_q->busy, 0);
1617 if (ioc->msix_enable) 1624 if (ioc->msix_enable)
1618 snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", 1625 snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d",
@@ -1647,6 +1654,7 @@ static void
1647_base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) 1654_base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc)
1648{ 1655{
1649 unsigned int cpu, nr_cpus, nr_msix, index = 0; 1656 unsigned int cpu, nr_cpus, nr_msix, index = 0;
1657 struct adapter_reply_queue *reply_q;
1650 1658
1651 if (!_base_is_controller_msix_enabled(ioc)) 1659 if (!_base_is_controller_msix_enabled(ioc))
1652 return; 1660 return;
@@ -1661,20 +1669,30 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc)
1661 1669
1662 cpu = cpumask_first(cpu_online_mask); 1670 cpu = cpumask_first(cpu_online_mask);
1663 1671
1664 do { 1672 list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
1673
1665 unsigned int i, group = nr_cpus / nr_msix; 1674 unsigned int i, group = nr_cpus / nr_msix;
1666 1675
1676 if (cpu >= nr_cpus)
1677 break;
1678
1667 if (index < nr_cpus % nr_msix) 1679 if (index < nr_cpus % nr_msix)
1668 group++; 1680 group++;
1669 1681
1670 for (i = 0 ; i < group ; i++) { 1682 for (i = 0 ; i < group ; i++) {
1671 ioc->cpu_msix_table[cpu] = index; 1683 ioc->cpu_msix_table[cpu] = index;
1684 cpumask_or(reply_q->affinity_hint,
1685 reply_q->affinity_hint, get_cpu_mask(cpu));
1672 cpu = cpumask_next(cpu, cpu_online_mask); 1686 cpu = cpumask_next(cpu, cpu_online_mask);
1673 } 1687 }
1674 1688
1689 if (irq_set_affinity_hint(reply_q->vector,
1690 reply_q->affinity_hint))
1691 dinitprintk(ioc, pr_info(MPT3SAS_FMT
1692 "error setting affinity hint for irq vector %d\n",
1693 ioc->name, reply_q->vector));
1675 index++; 1694 index++;
1676 1695 }
1677 } while (cpu < nr_cpus);
1678} 1696}
1679 1697
1680/** 1698/**
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 7e9f55baa1bc..afa881682bef 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -507,6 +507,7 @@ struct adapter_reply_queue {
507 Mpi2ReplyDescriptorsUnion_t *reply_post_free; 507 Mpi2ReplyDescriptorsUnion_t *reply_post_free;
508 char name[MPT_NAME_LENGTH]; 508 char name[MPT_NAME_LENGTH];
509 atomic_t busy; 509 atomic_t busy;
510 cpumask_var_t affinity_hint;
510 struct list_head list; 511 struct list_head list;
511}; 512};
512 513