Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -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);
}
+4 −0
Original line number Diff line number Diff line
@@ -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;
+25 −0
Original line number Diff line number Diff line
@@ -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,