All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Add RTDM APIs for interrupt affinity configuration
@ 2021-07-02 14:27 Jan Kiszka
  2021-07-02 14:27 ` [PATCH 1/4] cobalt/intr: Fix cpumask argument type of xnintr_affinity Jan Kiszka
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Jan Kiszka @ 2021-07-02 14:27 UTC (permalink / raw)
  To: xenomai

Requested by users who were already calling lower-level APIs instead.

Jan

Jan Kiszka (4):
  cobalt/intr: Fix cpumask argument type of xnintr_affinity
  cobalt/intr: Add error handling to xnintr_affinity
  cobalt/intr: Enhance xnintr_attach with an initial cpumask
  cobalt/rtdm: Introduce IRQ affinity services

 include/cobalt/kernel/intr.h        |  5 ++-
 include/cobalt/kernel/rtdm/driver.h | 12 +++++++
 kernel/cobalt/dovetail/intr.c       | 24 +++++++++----
 kernel/cobalt/ipipe/intr.c          | 36 +++++++++++++++++---
 kernel/cobalt/rtdm/drvlib.c         | 52 +++++++++++++++++++++++++++--
 5 files changed, 113 insertions(+), 16 deletions(-)

-- 
2.26.2



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] cobalt/intr: Fix cpumask argument type of xnintr_affinity
  2021-07-02 14:27 [PATCH 0/4] Add RTDM APIs for interrupt affinity configuration Jan Kiszka
@ 2021-07-02 14:27 ` Jan Kiszka
  2021-07-02 14:27 ` [PATCH 2/4] cobalt/intr: Add error handling to xnintr_affinity Jan Kiszka
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Jan Kiszka @ 2021-07-02 14:27 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

Passing a potentially large mask by value was a bad idea of I-pipe.
Dovetail uses the kernel API, and that does it right. So adjust our
internal abstraction - which is unused so far anyway.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/intr.h  | 2 +-
 kernel/cobalt/dovetail/intr.c | 4 ++--
 kernel/cobalt/ipipe/intr.c    | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/cobalt/kernel/intr.h b/include/cobalt/kernel/intr.h
index 2636c2cbc5..6db4cfd905 100644
--- a/include/cobalt/kernel/intr.h
+++ b/include/cobalt/kernel/intr.h
@@ -125,7 +125,7 @@ void xnintr_enable(struct xnintr *intr);
 void xnintr_disable(struct xnintr *intr);
 
 void xnintr_affinity(struct xnintr *intr,
-		     cpumask_t cpumask);
+		     const cpumask_t *cpumask);
 
 #ifdef CONFIG_XENO_OPT_STATS_IRQS
 
diff --git a/kernel/cobalt/dovetail/intr.c b/kernel/cobalt/dovetail/intr.c
index 60d5bf882c..7953050fb0 100644
--- a/kernel/cobalt/dovetail/intr.c
+++ b/kernel/cobalt/dovetail/intr.c
@@ -118,12 +118,12 @@ void xnintr_disable(struct xnintr *intr)
 }
 EXPORT_SYMBOL_GPL(xnintr_disable);
 
-void xnintr_affinity(struct xnintr *intr, cpumask_t cpumask)
+void xnintr_affinity(struct xnintr *intr, const cpumask_t *cpumask)
 {
 	int ret;
 
 	secondary_mode_only();
-	ret = irq_set_affinity_hint(intr->irq, &cpumask);
+	ret = irq_set_affinity_hint(intr->irq, cpumask);
 
 	WARN_ON_ONCE(ret);
 }
diff --git a/kernel/cobalt/ipipe/intr.c b/kernel/cobalt/ipipe/intr.c
index 0c1cc4be45..0d2c515af8 100644
--- a/kernel/cobalt/ipipe/intr.c
+++ b/kernel/cobalt/ipipe/intr.c
@@ -992,11 +992,11 @@ EXPORT_SYMBOL_GPL(xnintr_disable);
  *
  * @coretags{secondary-only}
  */
-void xnintr_affinity(struct xnintr *intr, cpumask_t cpumask)
+void xnintr_affinity(struct xnintr *intr, const cpumask_t *cpumask)
 {
 	secondary_mode_only();
 #ifdef CONFIG_SMP
-	ipipe_set_irq_affinity(intr->irq, cpumask);
+	ipipe_set_irq_affinity(intr->irq, *cpumask);
 #endif
 }
 EXPORT_SYMBOL_GPL(xnintr_affinity);
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] cobalt/intr: Add error handling to xnintr_affinity
  2021-07-02 14:27 [PATCH 0/4] Add RTDM APIs for interrupt affinity configuration Jan Kiszka
  2021-07-02 14:27 ` [PATCH 1/4] cobalt/intr: Fix cpumask argument type of xnintr_affinity Jan Kiszka
@ 2021-07-02 14:27 ` Jan Kiszka
  2021-07-02 14:27 ` [PATCH 3/4] cobalt/intr: Enhance xnintr_attach with an initial cpumask Jan Kiszka
  2021-07-02 14:27 ` [PATCH 4/4] cobalt/rtdm: Introduce IRQ affinity services Jan Kiszka
  3 siblings, 0 replies; 5+ messages in thread
From: Jan Kiszka @ 2021-07-02 14:27 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

This function should respect the supported cpu set and report an error
if the specified set has no intersection with it. It should also return
potential errors for the underlying pipeline code.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/intr.h  |  3 +--
 kernel/cobalt/dovetail/intr.c | 11 +++++++----
 kernel/cobalt/ipipe/intr.c    | 16 +++++++++++++---
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/include/cobalt/kernel/intr.h b/include/cobalt/kernel/intr.h
index 6db4cfd905..9177141cba 100644
--- a/include/cobalt/kernel/intr.h
+++ b/include/cobalt/kernel/intr.h
@@ -124,8 +124,7 @@ void xnintr_enable(struct xnintr *intr);
 
 void xnintr_disable(struct xnintr *intr);
 
-void xnintr_affinity(struct xnintr *intr,
-		     const cpumask_t *cpumask);
+int xnintr_affinity(struct xnintr *intr, const cpumask_t *cpumask);
 
 #ifdef CONFIG_XENO_OPT_STATS_IRQS
 
diff --git a/kernel/cobalt/dovetail/intr.c b/kernel/cobalt/dovetail/intr.c
index 7953050fb0..da36f74462 100644
--- a/kernel/cobalt/dovetail/intr.c
+++ b/kernel/cobalt/dovetail/intr.c
@@ -118,13 +118,16 @@ void xnintr_disable(struct xnintr *intr)
 }
 EXPORT_SYMBOL_GPL(xnintr_disable);
 
-void xnintr_affinity(struct xnintr *intr, const cpumask_t *cpumask)
+int xnintr_affinity(struct xnintr *intr, const cpumask_t *cpumask)
 {
-	int ret;
+	cpumask_t effective_mask;
 
 	secondary_mode_only();
-	ret = irq_set_affinity_hint(intr->irq, cpumask);
 
-	WARN_ON_ONCE(ret);
+	cpumask_and(&effective_mask, &xnsched_realtime_cpus, cpumask);
+	if (cpumask_empty(&effective_mask))
+		return -EINVAL;
+
+	return irq_set_affinity_hint(intr->irq, &effective_mask);
 }
 EXPORT_SYMBOL_GPL(xnintr_affinity);
diff --git a/kernel/cobalt/ipipe/intr.c b/kernel/cobalt/ipipe/intr.c
index 0d2c515af8..29adf1a7ae 100644
--- a/kernel/cobalt/ipipe/intr.c
+++ b/kernel/cobalt/ipipe/intr.c
@@ -992,11 +992,21 @@ EXPORT_SYMBOL_GPL(xnintr_disable);
  *
  * @coretags{secondary-only}
  */
-void xnintr_affinity(struct xnintr *intr, const cpumask_t *cpumask)
+int xnintr_affinity(struct xnintr *intr, const cpumask_t *cpumask)
 {
-	secondary_mode_only();
 #ifdef CONFIG_SMP
-	ipipe_set_irq_affinity(intr->irq, *cpumask);
+	cpumask_t effective_mask;
+
+	secondary_mode_only();
+
+	cpumask_and(&effective_mask, &xnsched_realtime_cpus, cpumask);
+	if (cpumask_empty(&effective_mask))
+		return -EINVAL;
+
+	return ipipe_set_irq_affinity(intr->irq, effective_mask);
+#else
+	secondary_mode_only();
+	return 0;
 #endif
 }
 EXPORT_SYMBOL_GPL(xnintr_affinity);
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] cobalt/intr: Enhance xnintr_attach with an initial cpumask
  2021-07-02 14:27 [PATCH 0/4] Add RTDM APIs for interrupt affinity configuration Jan Kiszka
  2021-07-02 14:27 ` [PATCH 1/4] cobalt/intr: Fix cpumask argument type of xnintr_affinity Jan Kiszka
  2021-07-02 14:27 ` [PATCH 2/4] cobalt/intr: Add error handling to xnintr_affinity Jan Kiszka
@ 2021-07-02 14:27 ` Jan Kiszka
  2021-07-02 14:27 ` [PATCH 4/4] cobalt/rtdm: Introduce IRQ affinity services Jan Kiszka
  3 siblings, 0 replies; 5+ messages in thread
From: Jan Kiszka @ 2021-07-02 14:27 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

This allows to start up interrupts with a specific affinity already set.
Will be used by a new RTDM service.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/intr.h  |  2 +-
 kernel/cobalt/dovetail/intr.c | 13 +++++++++++--
 kernel/cobalt/ipipe/intr.c    | 20 ++++++++++++++++++--
 kernel/cobalt/rtdm/drvlib.c   |  2 +-
 4 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/include/cobalt/kernel/intr.h b/include/cobalt/kernel/intr.h
index 9177141cba..393ad96830 100644
--- a/include/cobalt/kernel/intr.h
+++ b/include/cobalt/kernel/intr.h
@@ -116,7 +116,7 @@ int xnintr_init(struct xnintr *intr,
 void xnintr_destroy(struct xnintr *intr);
 
 int xnintr_attach(struct xnintr *intr,
-		  void *cookie);
+		  void *cookie, const cpumask_t *cpumask);
 
 void xnintr_detach(struct xnintr *intr);
 
diff --git a/kernel/cobalt/dovetail/intr.c b/kernel/cobalt/dovetail/intr.c
index da36f74462..a9459b7a81 100644
--- a/kernel/cobalt/dovetail/intr.c
+++ b/kernel/cobalt/dovetail/intr.c
@@ -83,15 +83,24 @@ void xnintr_destroy(struct xnintr *intr)
 }
 EXPORT_SYMBOL_GPL(xnintr_destroy);
 
-int xnintr_attach(struct xnintr *intr, void *cookie)
+int xnintr_attach(struct xnintr *intr, void *cookie, const cpumask_t *cpumask)
 {
+	cpumask_t tmp_mask, *effective_mask;
 	int ret;
 
 	secondary_mode_only();
 
 	intr->cookie = cookie;
 
-	ret = irq_set_affinity_hint(intr->irq, &xnsched_realtime_cpus);
+	if (!cpumask) {
+		effective_mask = &xnsched_realtime_cpus;
+	} else {
+		effective_mask = &tmp_mask;
+		cpumask_and(effective_mask, &xnsched_realtime_cpus, cpumask);
+		if (cpumask_empty(effective_mask))
+			return -EINVAL;
+	}
+	ret = irq_set_affinity_hint(intr->irq, effective_mask);
 	if (ret)
 		return ret;
 
diff --git a/kernel/cobalt/ipipe/intr.c b/kernel/cobalt/ipipe/intr.c
index 29adf1a7ae..378c7f07d5 100644
--- a/kernel/cobalt/ipipe/intr.c
+++ b/kernel/cobalt/ipipe/intr.c
@@ -828,6 +828,9 @@ EXPORT_SYMBOL_GPL(xnintr_destroy);
  * @param cookie A user-defined opaque value which is stored into the
  * descriptor for further retrieval by the interrupt handler.
  *
+ * @param cpumask Initial CPU affinity of the interrupt. If NULL, affinity is
+ * set to all real-time CPUs.
+ *
  * @return 0 is returned on success. Otherwise:
  *
  * - -EINVAL is returned if an error occurred while attaching the
@@ -843,8 +846,11 @@ EXPORT_SYMBOL_GPL(xnintr_destroy);
  * @note Attaching an interrupt descriptor resets the tracked number
  * of IRQ receipts to zero.
  */
-int xnintr_attach(struct xnintr *intr, void *cookie)
+int xnintr_attach(struct xnintr *intr, void *cookie, const cpumask_t *cpumask)
 {
+#ifdef CONFIG_SMP
+	cpumask_t tmp_mask, *effective_mask;
+#endif
 	int ret;
 
 	secondary_mode_only();
@@ -854,7 +860,17 @@ int xnintr_attach(struct xnintr *intr, void *cookie)
 	clear_irqstats(intr);
 
 #ifdef CONFIG_SMP
-	ipipe_set_irq_affinity(intr->irq, xnsched_realtime_cpus);
+	if (!cpumask) {
+		effective_mask = &xnsched_realtime_cpus;
+	} else {
+		effective_mask = &tmp_mask;
+		cpumask_and(effective_mask, &xnsched_realtime_cpus, cpumask);
+		if (cpumask_empty(effective_mask))
+			return -EINVAL;
+	}
+	ret = ipipe_set_irq_affinity(intr->irq, *effective_mask);
+	if (ret)
+		return ret;
 #endif /* CONFIG_SMP */
 
 	raw_spin_lock(&intr->lock);
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index 2394212846..e97a475c9a 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -1455,7 +1455,7 @@ int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
 	if (err)
 		return err;
 
-	err = xnintr_attach(irq_handle, arg);
+	err = xnintr_attach(irq_handle, arg, NULL);
 	if (err) {
 		xnintr_destroy(irq_handle);
 		return err;
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] cobalt/rtdm: Introduce IRQ affinity services
  2021-07-02 14:27 [PATCH 0/4] Add RTDM APIs for interrupt affinity configuration Jan Kiszka
                   ` (2 preceding siblings ...)
  2021-07-02 14:27 ` [PATCH 3/4] cobalt/intr: Enhance xnintr_attach with an initial cpumask Jan Kiszka
@ 2021-07-02 14:27 ` Jan Kiszka
  3 siblings, 0 replies; 5+ messages in thread
From: Jan Kiszka @ 2021-07-02 14:27 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

Add rtdm_irq_request_affine and rtdm_irq_set_affinity to start IRQs or
specific CPUs or move them around. So far, this was unsupported and made
users bypass layer to configure the desired affinity. Starting with the
right affinity also avoids hitting the wrong CPU at least once before
the IRQ can be live-migrated.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/rtdm/driver.h | 12 +++++++
 kernel/cobalt/rtdm/drvlib.c         | 52 +++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h
index 1955254cc6..db1dfc6367 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -27,6 +27,7 @@
 #define _COBALT_RTDM_DRIVER_H
 
 #include <asm/atomic.h>
+#include <linux/cpumask.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/cdev.h>
@@ -854,6 +855,11 @@ int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
 		     rtdm_irq_handler_t handler, unsigned long flags,
 		     const char *device_name, void *arg);
 
+int rtdm_irq_request_affine(rtdm_irq_t *irq_handle, unsigned int irq_no,
+			    rtdm_irq_handler_t handler, unsigned long flags,
+			    const char *device_name, void *arg,
+			    const cpumask_t *cpumask);
+
 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
 static inline int rtdm_irq_free(rtdm_irq_t *irq_handle)
 {
@@ -874,6 +880,12 @@ static inline int rtdm_irq_disable(rtdm_irq_t *irq_handle)
 	xnintr_disable(irq_handle);
 	return 0;
 }
+
+static inline int rtdm_irq_set_affinity(rtdm_irq_t *irq_handle,
+					const cpumask_t *cpumask)
+{
+	return xnintr_affinity(irq_handle, cpumask);
+}
 #endif /* !DOXYGEN_CPP */
 
 /* --- non-real-time signalling services --- */
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index e97a475c9a..7b7b0830c2 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -1442,6 +1442,41 @@ EXPORT_SYMBOL_GPL(rtdm_mutex_timedlock);
 int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
 		     rtdm_irq_handler_t handler, unsigned long flags,
 		     const char *device_name, void *arg)
+{
+	return rtdm_irq_request_affine(irq_handle, irq_no, handler, flags,
+				       device_name, arg, NULL);
+}
+
+EXPORT_SYMBOL_GPL(rtdm_irq_request);
+
+/**
+ * @brief Register an interrupt handler
+ *
+ * This function registers the provided handler with an IRQ line and enables
+ * the line.
+ *
+ * @param[in,out] irq_handle IRQ handle
+ * @param[in] irq_no Line number of the addressed IRQ
+ * @param[in] handler Interrupt handler
+ * @param[in] flags Registration flags, see @ref RTDM_IRQTYPE_xxx for details
+ * @param[in] device_name Device name to show up in real-time IRQ lists
+ * @param[in] arg Pointer to be passed to the interrupt handler on invocation
+ * @param[in] cpumask CPU affinity of the interrupt
+ *
+ * @return 0 on success, otherwise:
+ *
+ * - -EINVAL is returned if an invalid parameter was passed.
+ *
+ * - -EBUSY is returned if the specified IRQ line is already in use.
+ *
+ * - -ENOSYS is returned if the real-time core is disabled.
+ *
+ * @coretags{secondary-only}
+ */
+int rtdm_irq_request_affine(rtdm_irq_t *irq_handle, unsigned int irq_no,
+			    rtdm_irq_handler_t handler, unsigned long flags,
+			    const char *device_name, void *arg,
+			    const cpumask_t *cpumask)
 {
 	int err;
 
@@ -1455,7 +1490,7 @@ int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
 	if (err)
 		return err;
 
-	err = xnintr_attach(irq_handle, arg, NULL);
+	err = xnintr_attach(irq_handle, arg, cpumask);
 	if (err) {
 		xnintr_destroy(irq_handle);
 		return err;
@@ -1466,7 +1501,7 @@ int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
 	return 0;
 }
 
-EXPORT_SYMBOL_GPL(rtdm_irq_request);
+EXPORT_SYMBOL_GPL(rtdm_irq_request_affine);
 
 #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
 /**
@@ -1524,6 +1559,19 @@ int rtdm_irq_enable(rtdm_irq_t *irq_handle);
  * @coretags{secondary-only}
  */
 int rtdm_irq_disable(rtdm_irq_t *irq_handle);
+
+/**
+ * @brief Set interrupt affinity
+ *
+ * @param[in] irq_handle IRQ handle as returned by rtdm_irq_request()
+ *
+ * @param[in] cpumask The new CPU affinity of the interrupt
+ *
+ * @return 0 on success, otherwise negative error code
+ *
+ * @coretags{secondary-only}
+ */
+int rtdm_irq_set_affinity(rtdm_irq_t *irq_handle, const cpumask_t *cpumask);
 #endif /* DOXYGEN_CPP */
 
 /** @} Interrupt Management Services */
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-07-02 14:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-02 14:27 [PATCH 0/4] Add RTDM APIs for interrupt affinity configuration Jan Kiszka
2021-07-02 14:27 ` [PATCH 1/4] cobalt/intr: Fix cpumask argument type of xnintr_affinity Jan Kiszka
2021-07-02 14:27 ` [PATCH 2/4] cobalt/intr: Add error handling to xnintr_affinity Jan Kiszka
2021-07-02 14:27 ` [PATCH 3/4] cobalt/intr: Enhance xnintr_attach with an initial cpumask Jan Kiszka
2021-07-02 14:27 ` [PATCH 4/4] cobalt/rtdm: Introduce IRQ affinity services Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.