Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sreekanth Reddy and committed by
Christoph Hellwig
14b3114d a03bd153

+44 -6
+21 -3
drivers/scsi/mpt2sas/mpt2sas_base.c
··· 1300 1300 1301 1301 list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { 1302 1302 list_del(&reply_q->list); 1303 + irq_set_affinity_hint(reply_q->vector, NULL); 1304 + free_cpumask_var(reply_q->affinity_hint); 1303 1305 synchronize_irq(reply_q->vector); 1304 1306 free_irq(reply_q->vector, reply_q); 1305 1307 kfree(reply_q); ··· 1331 1329 reply_q->ioc = ioc; 1332 1330 reply_q->msix_index = index; 1333 1331 reply_q->vector = vector; 1332 + 1333 + if (!alloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL)) 1334 + return -ENOMEM; 1335 + cpumask_clear(reply_q->affinity_hint); 1336 + 1334 1337 atomic_set(&reply_q->busy, 0); 1335 1338 if (ioc->msix_enable) 1336 1339 snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", ··· 1370 1363 _base_assign_reply_queues(struct MPT2SAS_ADAPTER *ioc) 1371 1364 { 1372 1365 unsigned int cpu, nr_cpus, nr_msix, index = 0; 1366 + struct adapter_reply_queue *reply_q; 1373 1367 1374 1368 if (!_base_is_controller_msix_enabled(ioc)) 1375 1369 return; ··· 1385 1377 1386 1378 cpu = cpumask_first(cpu_online_mask); 1387 1379 1388 - do { 1380 + list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { 1381 + 1389 1382 unsigned int i, group = nr_cpus / nr_msix; 1383 + 1384 + if (cpu >= nr_cpus) 1385 + break; 1390 1386 1391 1387 if (index < nr_cpus % nr_msix) 1392 1388 group++; 1393 1389 1394 1390 for (i = 0 ; i < group ; i++) { 1395 1391 ioc->cpu_msix_table[cpu] = index; 1392 + cpumask_or(reply_q->affinity_hint, 1393 + reply_q->affinity_hint, get_cpu_mask(cpu)); 1396 1394 cpu = cpumask_next(cpu, cpu_online_mask); 1397 1395 } 1398 1396 1397 + if (irq_set_affinity_hint(reply_q->vector, 1398 + reply_q->affinity_hint)) 1399 + dinitprintk(ioc, pr_info(MPT2SAS_FMT 1400 + "error setting affinity hint for irq vector %d\n", 1401 + ioc->name, reply_q->vector)); 1399 1402 index++; 1400 - 1401 - } while (cpu < nr_cpus); 1403 + } 1402 1404 } 1403 1405 1404 1406 /**
+1
drivers/scsi/mpt2sas/mpt2sas_base.h
··· 587 587 Mpi2ReplyDescriptorsUnion_t *reply_post_free; 588 588 char name[MPT_NAME_LENGTH]; 589 589 atomic_t busy; 590 + cpumask_var_t affinity_hint; 590 591 struct list_head list; 591 592 }; 592 593
+21 -3
drivers/scsi/mpt3sas/mpt3sas_base.c
··· 1584 1584 1585 1585 list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { 1586 1586 list_del(&reply_q->list); 1587 + irq_set_affinity_hint(reply_q->vector, NULL); 1588 + free_cpumask_var(reply_q->affinity_hint); 1587 1589 synchronize_irq(reply_q->vector); 1588 1590 free_irq(reply_q->vector, reply_q); 1589 1591 kfree(reply_q); ··· 1615 1613 reply_q->ioc = ioc; 1616 1614 reply_q->msix_index = index; 1617 1615 reply_q->vector = vector; 1616 + 1617 + if (!alloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL)) 1618 + return -ENOMEM; 1619 + cpumask_clear(reply_q->affinity_hint); 1620 + 1618 1621 atomic_set(&reply_q->busy, 0); 1619 1622 if (ioc->msix_enable) 1620 1623 snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", ··· 1654 1647 _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) 1655 1648 { 1656 1649 unsigned int cpu, nr_cpus, nr_msix, index = 0; 1650 + struct adapter_reply_queue *reply_q; 1657 1651 1658 1652 if (!_base_is_controller_msix_enabled(ioc)) 1659 1653 return; ··· 1669 1661 1670 1662 cpu = cpumask_first(cpu_online_mask); 1671 1663 1672 - do { 1664 + list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { 1665 + 1673 1666 unsigned int i, group = nr_cpus / nr_msix; 1667 + 1668 + if (cpu >= nr_cpus) 1669 + break; 1674 1670 1675 1671 if (index < nr_cpus % nr_msix) 1676 1672 group++; 1677 1673 1678 1674 for (i = 0 ; i < group ; i++) { 1679 1675 ioc->cpu_msix_table[cpu] = index; 1676 + cpumask_or(reply_q->affinity_hint, 1677 + reply_q->affinity_hint, get_cpu_mask(cpu)); 1680 1678 cpu = cpumask_next(cpu, cpu_online_mask); 1681 1679 } 1682 1680 1681 + if (irq_set_affinity_hint(reply_q->vector, 1682 + reply_q->affinity_hint)) 1683 + dinitprintk(ioc, pr_info(MPT3SAS_FMT 1684 + "error setting affinity hint for irq vector %d\n", 1685 + ioc->name, reply_q->vector)); 1683 1686 index++; 1684 - 1685 - } while (cpu < nr_cpus); 1687 + } 1686 1688 } 1687 1689 1688 1690 /**
+1
drivers/scsi/mpt3sas/mpt3sas_base.h
··· 507 507 Mpi2ReplyDescriptorsUnion_t *reply_post_free; 508 508 char name[MPT_NAME_LENGTH]; 509 509 atomic_t busy; 510 + cpumask_var_t affinity_hint; 510 511 struct list_head list; 511 512 }; 512 513