Commit b14db1f0 authored by Tadeusz Struk's avatar Tadeusz Struk Committed by Doug Ledford

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: default avatarDean Luick <dean.luick@intel.com>
Signed-off-by: default avatarTadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent c3f8de0b
......@@ -47,6 +47,7 @@
#include <linux/topology.h>
#include <linux/cpumask.h>
#include <linux/module.h>
#include <linux/cpumask.h>
#include "hfi.h"
#include "affinity.h"
......@@ -673,3 +674,70 @@ void hfi1_put_proc_affinity(int cpu)
}
spin_unlock(&affinity->lock);
}
/* Prevents concurrent reads and writes of the sdma_affinity attrib */
static DEFINE_MUTEX(sdma_affinity_mutex);
int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf,
size_t count)
{
struct hfi1_affinity_node *entry;
struct cpumask mask;
int ret, i;
spin_lock(&node_affinity.lock);
entry = node_affinity_lookup(dd->node);
spin_unlock(&node_affinity.lock);
if (!entry)
return -EINVAL;
ret = cpulist_parse(buf, &mask);
if (ret)
return ret;
if (!cpumask_subset(&mask, cpu_online_mask) || cpumask_empty(&mask)) {
dd_dev_warn(dd, "Invalid CPU mask\n");
return -EINVAL;
}
mutex_lock(&sdma_affinity_mutex);
/* reset the SDMA interrupt affinity details */
init_cpu_mask_set(&entry->def_intr);
cpumask_copy(&entry->def_intr.mask, &mask);
/*
* Reassign the affinity for each SDMA interrupt.
*/
for (i = 0; i < dd->num_msix_entries; i++) {
struct hfi1_msix_entry *msix;
msix = &dd->msix_entries[i];
if (msix->type != IRQ_SDMA)
continue;
ret = hfi1_get_irq_affinity(dd, msix);
if (ret)
break;
}
mutex_unlock(&sdma_affinity_mutex);
return ret ? ret : strnlen(buf, PAGE_SIZE);
}
int hfi1_get_sdma_affinity(struct hfi1_devdata *dd, char *buf)
{
struct hfi1_affinity_node *entry;
spin_lock(&node_affinity.lock);
entry = node_affinity_lookup(dd->node);
spin_unlock(&node_affinity.lock);
if (!entry)
return -EINVAL;
mutex_lock(&sdma_affinity_mutex);
cpumap_print_to_pagebuf(true, buf, &entry->def_intr.mask);
mutex_unlock(&sdma_affinity_mutex);
return strnlen(buf, PAGE_SIZE);
}
......@@ -102,6 +102,10 @@ int hfi1_get_proc_affinity(int);
/* Release a CPU used by a user process. */
void hfi1_put_proc_affinity(int);
int hfi1_get_sdma_affinity(struct hfi1_devdata *dd, char *buf);
int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf,
size_t count);
struct hfi1_affinity_node {
int node;
struct cpu_mask_set def_intr;
......
......@@ -49,6 +49,7 @@
#include "hfi.h"
#include "mad.h"
#include "trace.h"
#include "affinity.h"
/*
* Start of per-port congestion control structures and support code
......@@ -622,6 +623,27 @@ static ssize_t show_tempsense(struct device *device,
return ret;
}
static ssize_t show_sdma_affinity(struct device *device,
struct device_attribute *attr, char *buf)
{
struct hfi1_ibdev *dev =
container_of(device, struct hfi1_ibdev, rdi.ibdev.dev);
struct hfi1_devdata *dd = dd_from_dev(dev);
return hfi1_get_sdma_affinity(dd, buf);
}
static ssize_t store_sdma_affinity(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct hfi1_ibdev *dev =
container_of(device, struct hfi1_ibdev, rdi.ibdev.dev);
struct hfi1_devdata *dd = dd_from_dev(dev);
return hfi1_set_sdma_affinity(dd, buf, count);
}
/*
* end of per-unit (or driver, in some cases, but replicated
* per unit) functions
......@@ -636,6 +658,8 @@ static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL);
static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL);
static DEVICE_ATTR(tempsense, S_IRUGO, show_tempsense, NULL);
static DEVICE_ATTR(chip_reset, S_IWUSR, NULL, store_chip_reset);
static DEVICE_ATTR(sdma_affinity, S_IWUSR | S_IRUGO, show_sdma_affinity,
store_sdma_affinity);
static struct device_attribute *hfi1_attributes[] = {
&dev_attr_hw_rev,
......@@ -646,6 +670,7 @@ static struct device_attribute *hfi1_attributes[] = {
&dev_attr_boardversion,
&dev_attr_tempsense,
&dev_attr_chip_reset,
&dev_attr_sdma_affinity,
};
int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment