Skip to content

Commit b14db1f

Browse files
tstrukdledford
authored andcommitted
IB/hfi1: Add sysfs entry to override SDMA interrupt affinity
Add sysfs entry to allow user to override affinity for SDMA engine interrupts. Reviewed-by: Dean Luick <[email protected]> Signed-off-by: Tadeusz Struk <[email protected]> Signed-off-by: Dennis Dalessandro <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent c3f8de0 commit b14db1f

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

drivers/infiniband/hw/hfi1/affinity.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <linux/topology.h>
4848
#include <linux/cpumask.h>
4949
#include <linux/module.h>
50+
#include <linux/cpumask.h>
5051

5152
#include "hfi.h"
5253
#include "affinity.h"
@@ -673,3 +674,70 @@ void hfi1_put_proc_affinity(int cpu)
673674
}
674675
spin_unlock(&affinity->lock);
675676
}
677+
678+
/* Prevents concurrent reads and writes of the sdma_affinity attrib */
679+
static DEFINE_MUTEX(sdma_affinity_mutex);
680+
681+
int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf,
682+
size_t count)
683+
{
684+
struct hfi1_affinity_node *entry;
685+
struct cpumask mask;
686+
int ret, i;
687+
688+
spin_lock(&node_affinity.lock);
689+
entry = node_affinity_lookup(dd->node);
690+
spin_unlock(&node_affinity.lock);
691+
692+
if (!entry)
693+
return -EINVAL;
694+
695+
ret = cpulist_parse(buf, &mask);
696+
if (ret)
697+
return ret;
698+
699+
if (!cpumask_subset(&mask, cpu_online_mask) || cpumask_empty(&mask)) {
700+
dd_dev_warn(dd, "Invalid CPU mask\n");
701+
return -EINVAL;
702+
}
703+
704+
mutex_lock(&sdma_affinity_mutex);
705+
/* reset the SDMA interrupt affinity details */
706+
init_cpu_mask_set(&entry->def_intr);
707+
cpumask_copy(&entry->def_intr.mask, &mask);
708+
/*
709+
* Reassign the affinity for each SDMA interrupt.
710+
*/
711+
for (i = 0; i < dd->num_msix_entries; i++) {
712+
struct hfi1_msix_entry *msix;
713+
714+
msix = &dd->msix_entries[i];
715+
if (msix->type != IRQ_SDMA)
716+
continue;
717+
718+
ret = hfi1_get_irq_affinity(dd, msix);
719+
720+
if (ret)
721+
break;
722+
}
723+
724+
mutex_unlock(&sdma_affinity_mutex);
725+
return ret ? ret : strnlen(buf, PAGE_SIZE);
726+
}
727+
728+
int hfi1_get_sdma_affinity(struct hfi1_devdata *dd, char *buf)
729+
{
730+
struct hfi1_affinity_node *entry;
731+
732+
spin_lock(&node_affinity.lock);
733+
entry = node_affinity_lookup(dd->node);
734+
spin_unlock(&node_affinity.lock);
735+
736+
if (!entry)
737+
return -EINVAL;
738+
739+
mutex_lock(&sdma_affinity_mutex);
740+
cpumap_print_to_pagebuf(true, buf, &entry->def_intr.mask);
741+
mutex_unlock(&sdma_affinity_mutex);
742+
return strnlen(buf, PAGE_SIZE);
743+
}

drivers/infiniband/hw/hfi1/affinity.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ int hfi1_get_proc_affinity(int);
102102
/* Release a CPU used by a user process. */
103103
void hfi1_put_proc_affinity(int);
104104

105+
int hfi1_get_sdma_affinity(struct hfi1_devdata *dd, char *buf);
106+
int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf,
107+
size_t count);
108+
105109
struct hfi1_affinity_node {
106110
int node;
107111
struct cpu_mask_set def_intr;

drivers/infiniband/hw/hfi1/sysfs.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "hfi.h"
5050
#include "mad.h"
5151
#include "trace.h"
52+
#include "affinity.h"
5253

5354
/*
5455
* Start of per-port congestion control structures and support code
@@ -622,6 +623,27 @@ static ssize_t show_tempsense(struct device *device,
622623
return ret;
623624
}
624625

626+
static ssize_t show_sdma_affinity(struct device *device,
627+
struct device_attribute *attr, char *buf)
628+
{
629+
struct hfi1_ibdev *dev =
630+
container_of(device, struct hfi1_ibdev, rdi.ibdev.dev);
631+
struct hfi1_devdata *dd = dd_from_dev(dev);
632+
633+
return hfi1_get_sdma_affinity(dd, buf);
634+
}
635+
636+
static ssize_t store_sdma_affinity(struct device *device,
637+
struct device_attribute *attr,
638+
const char *buf, size_t count)
639+
{
640+
struct hfi1_ibdev *dev =
641+
container_of(device, struct hfi1_ibdev, rdi.ibdev.dev);
642+
struct hfi1_devdata *dd = dd_from_dev(dev);
643+
644+
return hfi1_set_sdma_affinity(dd, buf, count);
645+
}
646+
625647
/*
626648
* end of per-unit (or driver, in some cases, but replicated
627649
* per unit) functions
@@ -636,6 +658,8 @@ static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL);
636658
static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL);
637659
static DEVICE_ATTR(tempsense, S_IRUGO, show_tempsense, NULL);
638660
static DEVICE_ATTR(chip_reset, S_IWUSR, NULL, store_chip_reset);
661+
static DEVICE_ATTR(sdma_affinity, S_IWUSR | S_IRUGO, show_sdma_affinity,
662+
store_sdma_affinity);
639663

640664
static struct device_attribute *hfi1_attributes[] = {
641665
&dev_attr_hw_rev,
@@ -646,6 +670,7 @@ static struct device_attribute *hfi1_attributes[] = {
646670
&dev_attr_boardversion,
647671
&dev_attr_tempsense,
648672
&dev_attr_chip_reset,
673+
&dev_attr_sdma_affinity,
649674
};
650675

651676
int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num,

0 commit comments

Comments
 (0)