IB/hfi1: sdma engine affinity improvements
Subsystems (3)
cover IB/hfi1: sdma engine affinity improvements
This patch series is a set of performance improvements that deal with handling the affinity of sdma engines. This allows users more control over which CPU cores are used by the driver for sdma engines. It includes a way to dump out the current values and a handler for when the user changes irq affinity. The changes to sysfs are also documented.
This applies on top of the last series submitted and can be seen in my GitHub:
https://github.com/ddalessa/kernel/tree/for-4.9
---
Tadeusz Struk (5):
IB/hfi1: Add sysfs interface for affinity setup IB/hfi1: Add a new VL sysfs attribute for sdma engines IB/hfi1: Add irq affinity notification handler IB/hfi1: Add new debugfs sdma_cpu_list file IB/hfi1: Document new sysfs entries for hfi1 driver
Documentation/infiniband/sysfs.txt | 30 +++ drivers/infiniband/hw/hfi1/affinity.c | 112 +++++++++- drivers/infiniband/hw/hfi1/debugfs.c | 38 +++ drivers/infiniband/hw/hfi1/hfi.h | 3 drivers/infiniband/hw/hfi1/sdma.c | 353 ++++++++++++++++++++++++++++++++ drivers/infiniband/hw/hfi1/sdma.h | 10 + drivers/infiniband/hw/hfi1/sysfs.c | 103 +++++++++ drivers/infiniband/hw/hfi1/user_sdma.c | 9 - 8 files changed, 641 insertions(+), 17 deletions(-)
--
-Denny
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20160925144248.12088.71489.stgit-9QXIwq+3FY+1XWohqUldA0EOCMrvLtNR@public.gmane.org
PATCH 1/5 IB/hfi1: Add sysfs interface for affinity setup
From: Tadeusz Struk <[email protected]>
Some users want more control over which cpu cores are being used by the driver. For example, users might want to restrict the driver to some specified subset of the cores so that they can appropriately partition processes, irq handlers, and work threads.
To allow the user to fine tune system affinity settings new sysfs attributes are introduced per sdma engine. This patch adds a new attribute type for sdma engine and a new cpu_list attribute. When the user writes a cpu range to the cpu_list attribute the driver will create an internal cpu->sdma map, which will be used later as a look-up table to choose an optimal engine for a user requests.
--- drivers/infiniband/hw/hfi1/hfi.h | 2 drivers/infiniband/hw/hfi1/sdma.c | 310 ++++++++++++++++++++++++++++++++ drivers/infiniband/hw/hfi1/sdma.h | 8 + drivers/infiniband/hw/hfi1/sysfs.c | 90 +++++++++ drivers/infiniband/hw/hfi1/user_sdma.c | 9 - 5 files changed, 412 insertions(+), 7 deletions(-)
drivers/infiniband/hw/hfi1/hfi.h +2 -0
@@ -65,6 +65,7 @@#include <linux/i2c.h> #include <linux/i2c-algo-bit.h> #include <rdma/ib_hdrs.h> +#include <linux/rhashtable.h> #include <rdma/rdma_vt.h> #include "chip_registers.h"
@@ -1174,6 +1175,7 @@ struct hfi1_devdata {atomic_t aspm_disabled_cnt;struct hfi1_affinity *affinity; +struct rhashtable sdma_rht;struct kobject kobj; };
drivers/infiniband/hw/hfi1/sdma.c +310 -0
334 lines not on this page · raw message
drivers/infiniband/hw/hfi1/sdma.h +8 -0
@@ -413,6 +413,8 @@ struct sdma_engine {spinlock_t flushlist_lock;/* private: */ struct list_head flushlist; +struct cpumask cpu_mask; +struct kobject kobj; };int sdma_init (struct hfi1_devdata *dd,u8 port);
@@ -1059,6 +1061,12 @@ struct sdma_engine *sdma_select_engine_vl(u32 selector, u8 vl); +struct sdma_engine *sdma_select_user_engine (struct hfi1_devdata *dd, +u32 selector,u8 vl); +ssize_t sdma_get_cpu_to_sde_map (struct sdma_engine *sde,char *buf); +ssize_t sdma_set_cpu_to_sde_map (struct sdma_engine *sde,const char *buf, +size_t count); +int sdma_engine_get_vl (struct sdma_engine *sde);void sdma_seqfile_dump_sde (struct seq_file *s,struct sdma_engine *);#ifdef CONFIG_SDMA_VERBOSITY
drivers/infiniband/hw/hfi1/sysfs.c +89 -1
112 lines not on this page · raw message
drivers/infiniband/hw/hfi1/user_sdma.c +3 -6
@@ -548,7 +548,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,u8 opcode, sc, vl;int req_queued =0 ;u16 dlid; -u8 selector; +u32 selector;if (iovec[idx].iov_len <sizeof (info) +sizeof (req->hdr)) { hfi1_cdbg(
@@ -753,12 +753,9 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, dlid =be16_to_cpu (req->hdr.lrh[1 ]); selector =dlid_to_selector (dlid); + selector += uctxt->ctxt + fd->subctxt; + req->sde =sdma_select_user_engine (dd, selector, vl); -/* Have to select the engine */ - req->sde =sdma_select_engine_vl (dd, - (u32)(uctxt->ctxt + fd->subctxt + - selector), - vl);if (!req->sde || !sdma_running (req->sde)) { ret = -ECOMM ; goto free_req;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/5 IB/hfi1: Add a new VL sysfs attribute for sdma engines
In reply to a message not in the archiveFrom: Tadeusz Struk <[email protected]>
This patch adds a read-only "VL" attribute for the sysfs entry of each sdma engine. It will allow the user to check VL to sdma engine mappings.
--- drivers/infiniband/hw/hfi1/sysfs.c | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletions(-)
drivers/infiniband/hw/hfi1/sysfs.c +14 -1
@@ -826,12 +826,25 @@ static ssize_t sde_store_cpu_to_sde_map(struct sdma_engine *sde,return sdma_set_cpu_to_sde_map (sde, buf, count); } +static ssize_t sde_show_vl (struct sdma_engine *sde,char *buf) +{ +int vl; + + vl =sdma_engine_get_vl (sde); +if (vl <0 ) +return vl; + +return snprintf (buf,PAGE_SIZE ,"%d\n" , vl); +} + static SDE_ATTR(cpu_list, S_IWUSR | S_IRUGO, sde_show_cpu_to_sde_map, sde_store_cpu_to_sde_map); +static SDE_ATTR(vl, S_IRUGO, sde_show_vl, NULL);static struct sde_attribute *sde_attribs[] = { - &sde_attr_cpu_list + &sde_attr_cpu_list, + &sde_attr_vl };/*
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/5 IB/hfi1: Add irq affinity notification handler
In reply to a message not in the archiveFrom: Tadeusz Struk <[email protected]>
This patch adds an irq affinity notification handler. When a user changes interrupt affinity settings for an sdma engine, the driver needs to make changes to its internal sde structures and also update the affinity_hint.
--- drivers/infiniband/hw/hfi1/affinity.c | 112 ++++++++++++++++++++++++++++++--- drivers/infiniband/hw/hfi1/hfi.h | 1 2 files changed, 103 insertions(+), 10 deletions(-)
drivers/infiniband/hw/hfi1/affinity.c +102 -10
@@ -47,6 +47,7 @@#include <linux/topology.h> #include <linux/cpumask.h> #include <linux/module.h> +#include <linux/interrupt.h> #include "hfi.h" #include "affinity.h"
@@ -309,6 +310,101 @@ int hfi1_dev_affinity_init(struct hfi1_devdata *dd) }/* +* Function updates the irq affinity hint for msix after it has been changed +* by the user using the /proc/irq interface. This function only accepts +* one cpu in the mask. +*/ +static void hfi1_update_sdma_affinity (struct hfi1_msix_entry *msix,int cpu) +{ +struct sdma_engine *sde = msix->arg; +struct hfi1_devdata *dd = sde->dd; +struct hfi1_affinity_node *entry; +struct cpu_mask_set *set; +int i, old_cpu; + +if (cpu >num_online_cpus () || cpu == sde->cpu) +return ; + +mutex_lock (&node_affinity.lock); + entry =node_affinity_lookup (dd->node); +if (!entry) + goto unlock; + + old_cpu = sde->cpu; + sde->cpu = cpu; +cpumask_clear (&msix->mask); +cpumask_set_cpu (cpu, &msix->mask); +dd_dev_dbg (dd,"IRQ vector: %u, type %s engine %u -> cpu: %d\n" , + msix->msix.vector, irq_type_names[msix->type], + sde->this_idx, cpu); +irq_set_affinity_hint (msix->msix.vector, &msix->mask); + +/* +* Set the new cpu in the hfi1_affinity_node and clean +* the old cpu if it is not used by any other IRQ +*/ + set = &entry->def_intr; +cpumask_set_cpu (cpu, &set->mask); +cpumask_set_cpu (cpu, &set->used); +for (i =0 ; i < dd->num_msix_entries; i++) { +struct hfi1_msix_entry *other_msix; + + other_msix = &dd->msix_entries[i]; +if (other_msix->type !=IRQ_SDMA || other_msix == msix) +continue ; + +if (cpumask_test_cpu (old_cpu, &other_msix->mask)) + goto unlock; + } +cpumask_clear_cpu (old_cpu, &set->mask); +cpumask_clear_cpu (old_cpu, &set->used); +unlock: +mutex_unlock (&node_affinity.lock); +} + +static void hfi1_irq_notifier_notify (struct irq_affinity_notify *notify, +const cpumask_t *mask) +{ +int cpu =cpumask_first (mask); +struct hfi1_msix_entry *msix =container_of (notify, + struct hfi1_msix_entry, + notify); + +/* Only one CPU configuration supported currently */ +hfi1_update_sdma_affinity (msix, cpu); +} + +static void hfi1_irq_notifier_release (struct kref *ref) +{ +/* +* This is required by affinity notifier. We don't have anything to +* free here. +*/ +} + +static void hfi1_setup_sdma_notifier (struct hfi1_msix_entry *msix) +{ +struct irq_affinity_notify *notify = &msix->notify; + + notify->irq = msix->msix.vector; + notify->notify = hfi1_irq_notifier_notify; + notify->release = hfi1_irq_notifier_release; + +if (irq_set_affinity_notifier (notify->irq, notify)) +pr_err ("Failed to register sdma irq affinity notifier for irq %d\n" , + notify->irq); +} + +static void hfi1_cleanup_sdma_notifier (struct hfi1_msix_entry *msix) +{ +struct irq_affinity_notify *notify = &msix->notify; + +if (irq_set_affinity_notifier (notify->irq,NULL )) +pr_err ("Failed to cleanup sdma irq affinity notifier for irq %d\n" , + notify->irq); +} + +/* * Function sets the irq affinity for msix. * It *must* be called with node_affinity.lock held. */
@@ -374,22 +470,17 @@ static int get_irq_affinity(struct hfi1_devdata *dd,cpumask_set_cpu (cpu, &set->used); } -switch (msix->type) { -case IRQ_SDMA : - sde->cpu = cpu; -break ; -case IRQ_GENERAL : -case IRQ_RCVCTXT : -case IRQ_OTHER : -break ; - } -cpumask_set_cpu (cpu, &msix->mask);dd_dev_info (dd,"IRQ vector: %u, type %s %s -> cpu: %d\n" , msix->msix.vector, irq_type_names[msix->type], extra, cpu);irq_set_affinity_hint (msix->msix.vector, &msix->mask); +if (msix->type ==IRQ_SDMA ) { + sde->cpu = cpu; +hfi1_setup_sdma_notifier (msix); + } +free_cpumask_var (diff);return 0 ; }
@@ -417,6 +508,7 @@ void hfi1_put_irq_affinity(struct hfi1_devdata *dd,switch (msix->type) {case IRQ_SDMA : set = &entry->def_intr; +hfi1_cleanup_sdma_notifier (msix);break ;case IRQ_GENERAL :/* Don't do accounting for general contexts */
drivers/infiniband/hw/hfi1/hfi.h +1 -0
@@ -531,6 +531,7 @@ struct hfi1_msix_entry {void *arg;char name[MAX_NAME_SIZE ];cpumask_t mask; +struct irq_affinity_notify notify; };/* per-SL CCA information */
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/5 IB/hfi1: Add new debugfs sdma_cpu_list file
In reply to a message not in the archiveFrom: Tadeusz Struk <[email protected]>
Add a debugfs sdma_cpu_list file that can be used to examine the CPU to sdma engine assignments for the whole device.
--- drivers/infiniband/hw/hfi1/debugfs.c | 38 ++++++++++++++++++++++++++++++ drivers/infiniband/hw/hfi1/sdma.c | 43 ++++++++++++++++++++++++++++++++++ drivers/infiniband/hw/hfi1/sdma.h | 2 ++ 3 files changed, 83 insertions(+), 0 deletions(-)
drivers/infiniband/hw/hfi1/debugfs.c +38 -0
@@ -933,6 +933,43 @@ static const struct counter_info port_cntr_ops[] = { DEBUGFS_OPS("asic_flags", asic_flags_read, asic_flags_write), }; +static void *_sdma_cpu_list_seq_start (struct seq_file *s,loff_t *pos) +{ +if (*pos >=num_online_cpus ()) +return NULL ; + +return pos; +} + +static void *_sdma_cpu_list_seq_next (struct seq_file *s,void *v,loff_t *pos) +{ + ++*pos; +if (*pos >=num_online_cpus ()) +return NULL ; + +return pos; +} + +static void _sdma_cpu_list_seq_stop (struct seq_file *s,void *v) +{ +/* nothing allocated */ +} + +static int _sdma_cpu_list_seq_show (struct seq_file *s,void *v) +{ +struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private; +struct hfi1_devdata *dd =dd_from_dev (ibd); +loff_t *spos = v; +loff_t i = *spos; + +sdma_seqfile_dump_cpu_list (s, dd, (unsigned long )i); +return 0 ; +} + +DEBUGFS_SEQ_FILE_OPS (sdma_cpu_list); +DEBUGFS_SEQ_FILE_OPEN (sdma_cpu_list) +DEBUGFS_FILE_OPS (sdma_cpu_list); +void hfi1_dbg_ibdev_init (struct hfi1_ibdev *ibd) {char name[sizeof ("port0counters" ) +1 ];
@@ -961,6 +998,7 @@ void hfi1_dbg_ibdev_init(struct hfi1_ibdev *ibd)DEBUGFS_SEQ_FILE_CREATE (ctx_stats, ibd->hfi1_ibdev_dbg, ibd);DEBUGFS_SEQ_FILE_CREATE (qp_stats, ibd->hfi1_ibdev_dbg, ibd);DEBUGFS_SEQ_FILE_CREATE (sdes, ibd->hfi1_ibdev_dbg, ibd); +DEBUGFS_SEQ_FILE_CREATE (sdma_cpu_list, ibd->hfi1_ibdev_dbg, ibd);/* dev counter files */ for (i =0 ; i <ARRAY_SIZE (cntr_ops); i++) DEBUGFS_FILE_CREATE(cntr_ops[i].name,
drivers/infiniband/hw/hfi1/sdma.c +43 -0
49 lines not on this page · raw message
drivers/infiniband/hw/hfi1/sdma.h +2 -0
@@ -1068,6 +1068,8 @@ ssize_t sdma_set_cpu_to_sde_map(struct sdma_engine *sde, const char *buf, size_t count);int sdma_engine_get_vl (struct sdma_engine *sde);void sdma_seqfile_dump_sde (struct seq_file *s,struct sdma_engine *); +void sdma_seqfile_dump_cpu_list (struct seq_file *s,struct hfi1_devdata *dd, +unsigned long cpuid);#ifdef CONFIG_SDMA_VERBOSITY void sdma_dumpstate (struct sdma_engine *);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/5 IB/hfi1: Document new sysfs entries for hfi1 driver
In reply to a message not in the archiveFrom: Tadeusz Struk <[email protected]>
This patch adds description for the sdma engine related sysfs entries for the HFI1 driver.
--- Documentation/infiniband/sysfs.txt | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-)
Documentation/infiniband/sysfs.txt +30 -0
@@ -89,6 +89,36 @@ HFI1 nctxts - number of allowed contexts (PSM2) chip_reset - diagnostic (root only) boardversion - board version + + sdma<N>/ - one directory per sdma engine (0 - 15) + sdma<N>/cpu_list - read-write, list of cpus for user-process to sdma + engine assignment. + sdma<N>/vl - read-only, vl the sdma engine maps to. + + The new interface will give the user control on the affinity settings + for the hfi1 device. + As an example, to set an sdma engine irq affinity and thread affinity + of a user processes to use the sdma engine, which is "near" in terms + of NUMA configuration, or physical cpu location, the user will do: + + echo "3" > /proc/irq/<N>/smp_affinity_list + echo "4-7" > /sys/devices/.../sdma3/cpu_list + cat /sys/devices/.../sdma3/vl + 0 + echo "8" > /proc/irq/<M>/smp_affinity_list + echo "9-12" > /sys/devices/.../sdma4/cpu_list + cat /sys/devices/.../sdma4/vl + 1 + + to make sure that when a process runs on cpus 4,5,6, or 7, + and uses vl=0, then sdma engine 3 is selected by the driver, + and also the interrupt of the sdma engine 3 is steered to cpu 3. + Similarly, when a process runs on cpus 9,10,11, or 12 and sets vl=1, + then engine 4 will be selected and the irq of the sdma engine 4 is + steered to cpu 8. + This assumes that in the above N is the irq number of "sdma3", + and M is irq number of "sdma4" in the /proc/interrupts file. + ports/1/ CCMgtA/ cc_settings_bin - CCA tables used by PSM2
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 8 lines · Dennis Dalessandro
This patch series is a set of performance improvements that deal with handling the affinity of sdma engines. This allows users more control over which CPU cores are used by the driver for sdma engines. It includes a way to dump out the current values and a handler for when the user changes irq affinity. The changes to sysfs are also documented.
This applies on top of the last series submitted and can be seen in my GitHub:
https://github.com/ddalessa/kernel/tree/for-4.9
I've taken this. However, it does not escape me that this might have been more appropriate as part of rdmavt and working with qib in addition to hfi1. I decided to let it pass as it is because I know the qib driver is in deep maintenance mode and not active development, but what about when hfi2 comes about? Just keep that in mind.
Signature · 2 lines
Doug Ledford <[email protected]> GPG Key ID: 0E572FDD