Skip to contentSkip to conversation

Add generic routine for parsing map-like options on kernel cmd-line (repost:CC to LKML)

PATCH In review Remy Bohmer 4 participants 14 messages Dec 19, 2007 – Dec 20, 2007 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH 1/3 Add generic routine for parsing map-like options on kernel cmd-line (repost:CC to LKML)

This patch adds a generic routine to the kernel, so that a map of settings can be entered on the kernel commandline.

---

---
 include/linux/kernel.h |    1 
 lib/cmdline.c          |   58 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
include/linux/kernel.h +1 -0
Index: linux-2.6.24-rc5-rt1/include/linux/kernel.h
===================================================================
@@ -164,6 +164,7 @@ extern int vsscanf(const char *, const c
 
 extern int get_option(char **str, int *pint);
 extern char *get_options(const char *str, int nints, int *ints);
+extern int get_map_option(const char *str, const char *key, int *pint);
 extern unsigned long long memparse(char *ptr, char **retptr);
 
 extern int core_kernel_text(unsigned long addr);
lib/cmdline.c +58 -0

70 lines not on this page · raw message

#2 lore raw
Quoted 16 lines · On Wed, 19 Dec 2007 20:45:52 +0100 Remy Bohmer wrote:

This patch adds a generic routine to the kernel, so that a map of settings can be entered on the kernel commandline.

---

---
 include/linux/kernel.h |    1 
 lib/cmdline.c          |   58 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

Index: linux-2.6.24-rc5-rt1/lib/cmdline.c
===================================================================

lib/cmdline.c char *get_options(const char *str, int n · line 118

Quoted 4 lines
lib/cmdline.c +1 -0
@@ -114,6 +115,63 @@ char *get_options(const char *str, int n
 }
 
 /**
+ *	get_map_option - Parse integer from an option map

The @param lines (below) need to go here, immediately following the function short description (the line above). No intervening blank lines.

Quoted 8 lines
lib/cmdline.c +8 -0
+ *
+ *	This function parses an integer from an option map like
+ *           some_map=key1:99,key2:98,...,keyN:NN,NN
+ *	Only the value of the first match is returned, or if no
+ *	key option is given (key = NULL) the value of the first
+ *	field without a ':' is returned.
+ *
+ *	@str: option string

lib/cmdline.c char *get_options(const char *str, int n · line 136

Quoted 10 lines
lib/cmdline.c +10 -0
+ *	@key: The key inside the map, can be NULL
+ *	@pint: (output) integer value parsed from the map @str
+ *
+ *	Return values:
+ *	0 - no int in string
+ *	1 - int found
+ */
+int get_map_option(const char *str, const char *key, int *pint)
+{
+	char  buf[COMMAND_LINE_SIZE];

COMMAND_LINE_SIZE varies from 256 to 2048, depending on $ARCH. That's a bit too much to declare on a function's local stack -- unless you are very certain of the call tree to this point and that the total stack size is safe. Can you just kmalloc() this buf?

Quoted 26 lines
lib/cmdline.c +26 -0
+	char  *p, *substr;
+	int   found = 0;
+
+	/* We must copy the string to the stack, because strsep()
+	   changes it.*/
+	strncpy(buf, str, COMMAND_LINE_SIZE);
+	buf[COMMAND_LINE_SIZE-1] = '\0';
+
+	p = buf;
+	substr = strsep(&p, ",");
+	while ((!found) && (substr != NULL)) {
+		if (strlen(substr) != 0) {
+			if (key == NULL) {
+				/* Check for the absence of any ':' */
+				if (strchr(substr, ':') == NULL) {
+					sscanf(substr, "%d", pint);
+					found = 1;
+				}
+			} else {
+				/* check if the first part of the key matches */
+				if (!strncmp(substr, key, strlen(key))) {
+					substr += strlen(key);
+					/* Now the next char must be a ':',
+					   if not, search for the next match */
+					if (*substr == ':') {
+						substr++;

lib/cmdline.c char *get_options(const char *str, int n · line 172

Quoted 10 lines
lib/cmdline.c +10 -0
+						sscanf(substr, "%d", pint);
+						found = 1;
+					}
+				}
+			}
+		}
+		substr = strsep(&p, ",");
+	}
+	return found;
+}

---
~Randy

#3 lore raw

Hello Randy,

Sorry for the language errors, English is not my Native language, so I make these stupid errors...

Quoted 4 lines
Quoted 1 line

+ * get_map_option - Parse integer from an option map

The @param lines (below) need to go here, immediately following the function short description (the line above). No intervening blank lines.

OK, I will adapt that.

Quoted 9 lines

lib/cmdline.c char *get_options(const char *str, int n · line 136

Quoted 3 lines
lib/cmdline.c +3 -0
+int get_map_option(const char *str, const char *key, int *pint)
+{
+     char  buf[COMMAND_LINE_SIZE];

COMMAND_LINE_SIZE varies from 256 to 2048, depending on $ARCH. That's a bit too much to declare on a function's local stack -- unless you are very certain of the call tree to this point and that the total stack size is safe. Can you just kmalloc() this buf?

I know it is big on a 4k stack, and I also think it is not very nice... But kmalloc() panics the kernel if I do it as soon as in the __setup() code.

The problem is that the original string may not be modified by the cmdline-parser, and I do not know the length of the command up front, (except that it cannot be longer than this define). Allocating a global buffer is not safe and needs locking. So actually only what left for me was the stack... or rewrite the used C-library-routines completely myself, for this purpose only, which is also not nice.

I hope someone could point to me to another possibilty, that I did not think of yet.

Kind Regards,

Remy

Quoted 41 lines
Quoted 27 lines
lib/cmdline.c +26 -0
+     char  *p, *substr;
+     int   found = 0;
+
+     /* We must copy the string to the stack, because strsep()
+        changes it.*/
+     strncpy(buf, str, COMMAND_LINE_SIZE);
+     buf[COMMAND_LINE_SIZE-1] = '\0';
+
+     p = buf;
+     substr = strsep(&p, ",");
+     while ((!found) && (substr != NULL)) {
+             if (strlen(substr) != 0) {
+                     if (key == NULL) {
+                             /* Check for the absence of any ':' */
+                             if (strchr(substr, ':') == NULL) {
+                                     sscanf(substr, "%d", pint);
+                                     found = 1;
+                             }
+                     } else {
+                             /* check if the first part of the key matches */
+                             if (!strncmp(substr, key, strlen(key))) {
+                                     substr += strlen(key);
+                                     /* Now the next char must be a ':',
+                                        if not, search for the next match */
+                                     if (*substr == ':') {
+                                             substr++;

lib/cmdline.c char *get_options(const char *str, int n · line 172

Quoted 10 lines
lib/cmdline.c +10 -0
+                                             sscanf(substr, "%d", pint);
+                                             found = 1;
+                                     }
+                             }
+                     }
+             }
+             substr = strsep(&p, ",");
+     }
+     return found;
+}

---
~Randy

#4 lore raw

PATCH 2/3 Enable setting of IRQ-thread priorities from kernel cmdline (repost:CC to LKML)

In reply to a message not in the archive

The RT-patch originally creates all its IRQ-threads at priority 50. Of course, this is not a usable default for many realtime systems and therefor these priorities has to be tuneable for each RT-system. But, currently there is no way within the kernel to adjust this to the needs of the user. Some scripts are floating around to do this from userspace, but for several applications the priorities should already be set properly by the kernel itself before userland is started.

This patch changes this by adding a kernel cmd-line option that can handle a map of priorities.
It is based on the name of the driver that requests an interrupt, it does NOT use the IRQ-ID to prioritize a certain IRQ thread. This is designed this way because across several hardware-boards the IRQ-IDs can change, but not necessarily the drivers (interrupt handlers) name.

Remarks:
* There is a check for conflicts added, for situations where IRQ-sharing is detected with different priorities requested on the kernel cmd-line.
* Priorities are only set at creation time of the IRQ-thread.
* If userland overrules, it is NOT restored by this code.
* if no new kernel cmdline options are given, the kernel works as before, and all IRQ-threads start at 50.
* No wildcards are supported on the cmdline.

See kernel/Documentation/kernel-parameters.txt for usage info.

---
 Documentation/kernel-parameters.txt |    7 ++
 include/linux/irq.h                 |    1 
 kernel/irq/manage.c                 |  101 ++++++++++++++++++++++++++++++++----
 3 files changed, 98 insertions(+), 11 deletions(-)
Documentation/kernel-parameters.txt +7 -0
Index: linux-2.6.24-rc5-rt1/Documentation/kernel-parameters.txt
===================================================================
@@ -799,6 +799,13 @@ and is between 256 and 4096 characters. 
 	ips=		[HW,SCSI] Adaptec / IBM ServeRAID controller
 			See header of drivers/scsi/ips.c.
 
+	irq_pmap=	[IRQ-threading] List of priorities each interrupt
+			thread must have.
+			Format: irq_pmap=megasas:90,eth0:40,50
+			The first field without ':', is the default prio.
+			If this cmdline argument is ommitted, every thread
+			runs at prio 50.
+
 	ports=		[IP_VS_FTP] IPVS ftp helper module
 			Default is 21.
 			Up to 8 (IP_VS_APP_MAX_PORTS) ports
include/linux/irq.h +1 -0
Index: linux-2.6.24-rc5-rt1/include/linux/irq.h
===================================================================
@@ -169,6 +169,7 @@ struct irq_desc {
 	unsigned int		irqs_unhandled;
 	unsigned long		last_unhandled;	/* Aging timer for unhandled count */
 	struct task_struct	*thread;
+	int                     rt_prio;
 	wait_queue_head_t	wait_for_handler;
 	cycles_t		timestamp;
 	raw_spinlock_t		lock;
kernel/irq/manage.c +90 -11

157 lines not on this page · raw message

#5 lore raw

Re: [patch 2/3] Enable setting of IRQ-thread priorities from kernel cmdline (repost:CC to LKML)

Quoted 10 lines · On Wed, 19 Dec 2007 20:45:53 +0100 Remy Bohmer wrote:
 Documentation/kernel-parameters.txt |    7 ++
 include/linux/irq.h                 |    1 
 kernel/irq/manage.c                 |  101 ++++++++++++++++++++++++++++++++----
 3 files changed, 98 insertions(+), 11 deletions(-)

Index: linux-2.6.24-rc5-rt1/Documentation/kernel-parameters.txt
===================================================================

Documentation/kernel-parameters.txt and is between 256 and 4096 characters. · line 805

Quoted 7 lines
Documentation/kernel-parameters.txt +4 -0
@@ -799,6 +799,13 @@ and is between 256 and 4096 characters. 
 	ips=		[HW,SCSI] Adaptec / IBM ServeRAID controller
 			See header of drivers/scsi/ips.c.
 
+	irq_pmap=	[IRQ-threading] List of priorities each interrupt
+			thread must have.
+			Format: irq_pmap=megasas:90,eth0:40,50
+			The first field without ':', is the default prio.

Drop comma.

Documentation/kernel-parameters.txt and is between 256 and 4096 characters. · line 806

Quoted 1 line
Documentation/kernel-parameters.txt +1 -0
+			If this cmdline argument is ommitted, every thread

omitted,

Quoted 12 lines
Documentation/kernel-parameters.txt +2 -0
+			runs at prio 50.
+
 	ports=		[IP_VS_FTP] IPVS ftp helper module
 			Default is 21.
 			Up to 8 (IP_VS_APP_MAX_PORTS) ports

Index: linux-2.6.24-rc5-rt1/kernel/irq/manage.c
===================================================================

kernel/irq/manage.c void __init early_init_hardirqs(void) · line 927

Quoted 10 lines
kernel/irq/manage.c +7 -0
@@ -901,3 +918,65 @@ void __init early_init_hardirqs(void)
 	for (i = 0; i < NR_IRQS; i++)
 		init_waitqueue_head(&irq_desc[i].wait_for_handler);
 }
+
+#ifdef CONFIG_PREEMPT_HARDIRQS
+
+/*
+ * Lookup the interrupt thread priority
+ * A map for the priorities can be given on the kernel commandline.
+ * if name is NULL, or no kernel commandline options is given, the default
      If ...................................... option is given,

kernel/irq/manage.c void __init early_init_hardirqs(void) · line 932

Quoted 5 lines
kernel/irq/manage.c +5 -0
+ * prio is used, which is either MAX_PRIO/2, or the default given on the
+ * kernel commandline.
+ */
+static int get_irq_prio(const char *name)
+{

---
~Randy

#6 lore raw

Re: [patch 2/3] Enable setting of IRQ-thread priorities from kernel cmdline (repost:CC to LKML)

In reply to Remy Bohmer

include/linux/irq.h struct irq_desc { · line 173

Quoted 3 lines · Remy Bohmer
include/linux/irq.h +1 -0
 	struct task_struct	*thread;
+	int                     rt_prio;
 	wait_queue_head_t	wait_for_handler;

int rt_prio or unsigned int rt_prio, which one is better.

Thank you,

Jaswinder SIngh.

#7 lore raw

PATCH 3/3 Enable setting of IRQ-thread priorities from kernel cmdline. (repost:CC to LKML)

In reply to a message not in the archive

The RT-patch originally creates all its softirq-threads at priority 50. Of course, this is not a usable default for many realtime systems and therefor these priorities has to be tuneable for each RT-system. But, currently there is no way within the kernel to adjust this to the needs of the user. Some scripts are floating around to do this from userspace, but for several applications the priorities should already be set properly by the kernel itself before userland is started.

This patch changes this by adding a kernel cmd-line option that can handle a map of priorities.

Remarks:
* Priorities are only set at creation time of the softirq.
* Priorities has to be set per-cpu.
* If userland overrules, it is NOT restored by this code.
* if no new kernel cmdline options are given, the kernel works as before, and all softirqs start at 50.
* No wildcards are supported on the cmdline.

See kernel/Documentation/kernel-parameters.txt for usage info.

---
 Documentation/kernel-parameters.txt |   11 +++
 kernel/softirq.c                    |  105 ++++++++++++++++++++++++++++++------
 2 files changed, 99 insertions(+), 17 deletions(-)
Documentation/kernel-parameters.txt +11 -0
Index: linux-2.6.24-rc5-rt1/Documentation/kernel-parameters.txt
===================================================================
@@ -806,6 +806,17 @@ and is between 256 and 4096 characters. 
 			If this cmdline argument is ommitted, every thread
 			runs at prio 50.
 
+	sirq_pmap=	[IRQ-threading] List of priorities each softirq
+			thread must have.
+			Format: sirq_pmap=block/0:90,sched/0:75,50
+			The priorities have to be specified per-cpu.
+			The first field without ':', is the default prio.
+			The names have to match the softirq_names[] table in
+			kernel/softirq.c, (thus without 'softirq-' prefix) to
+			keep the cmd-line short.
+			If this cmdline argument is ommitted, every softirq
+			runs at prio 50.
+
 	ports=		[IP_VS_FTP] IPVS ftp helper module
 			Default is 21.
 			Up to 8 (IP_VS_APP_MAX_PORTS) ports
kernel/softirq.c +88 -17

136 lines not on this page · raw message

#8 lore raw

Re: [patch 3/3] Enable setting of IRQ-thread priorities from kernel cmdline. (repost:CC to LKML)

Quoted 9 lines · On Wed, 19 Dec 2007 20:45:54 +0100 Remy Bohmer wrote:
 Documentation/kernel-parameters.txt |   11 +++
 kernel/softirq.c                    |  105 ++++++++++++++++++++++++++++++------
 2 files changed, 99 insertions(+), 17 deletions(-)

Index: linux-2.6.24-rc5-rt1/Documentation/kernel-parameters.txt
===================================================================

Documentation/kernel-parameters.txt and is between 256 and 4096 characters. · line 813

Quoted 8 lines
Documentation/kernel-parameters.txt +5 -0
@@ -806,6 +806,17 @@ and is between 256 and 4096 characters. 
 			If this cmdline argument is ommitted, every thread
 			runs at prio 50.
 
+	sirq_pmap=	[IRQ-threading] List of priorities each softirq
+			thread must have.
+			Format: sirq_pmap=block/0:90,sched/0:75,50
+			The priorities have to be specified per-cpu.
+			The first field without ':', is the default prio.

Drop comma.

Documentation/kernel-parameters.txt and is between 256 and 4096 characters. · line 817

Quoted 4 lines
Documentation/kernel-parameters.txt +4 -0
+			The names have to match the softirq_names[] table in
+			kernel/softirq.c, (thus without 'softirq-' prefix) to
+			keep the cmd-line short.
+			If this cmdline argument is ommitted, every softirq

omitted,

Quoted 10 lines
Documentation/kernel-parameters.txt +2 -0
+			runs at prio 50.
+
 	ports=		[IP_VS_FTP] IPVS ftp helper module
 			Default is 21.
 			Up to 8 (IP_VS_APP_MAX_PORTS) ports

Index: linux-2.6.24-rc5-rt1/kernel/softirq.c
===================================================================

kernel/softirq.c int on_each_cpu(void (*func) (void *info · line 1069

Quoted 8 lines
kernel/softirq.c +5 -0
@@ -1051,3 +1062,63 @@ int on_each_cpu(void (*func) (void *info
 }
 EXPORT_SYMBOL(on_each_cpu);
 #endif
+
+/*
+ * Lookup the softirq thread priority.
+ * A map for the priorities can be given on the kernel commandline.
+ * if name is NULL, or no kernel commandline options is given, the default
      If ...................................... option is given,
Quoted 5 lines
kernel/softirq.c +5 -0
+ * prio is returned, which is either MAX_PRIO/2, or the default given on the
+ * kernel commandline.
+ */
+static int get_softirq_prio(const char *name)
+{

...

Quoted 1 line

+}

---
~Randy

#9 lore raw

Re: [patch 3/3] Enable setting of IRQ-thread priorities from kernel cmdline. (repost:CC to LKML)

In reply to Remy Bohmer
Quoted 2 lines · Remy Bohmer

The RT-patch originally creates all its softirq-threads at priority 50.

Is it possible to run softirq-threads or IRQs as a non-realtime tasks in RT kernel.

If yes, then how.

Thank you,

Jaswinder Singh.

#10 lore raw

Re: [patch 3/3] Enable setting of IRQ-thread priorities from kernel cmdline. (repost:CC to LKML)

Hello Jaswinder,

Quoted 2 lines

Is it possible to run softirq-threads or IRQs as a non-realtime tasks in RT kernel.

Currently the answer is no. (Unless overruled from userspace) I did not take this requirement into account.
So, Is this a serious requirement? Should this be possible? I cannot imagine a purpose in which that is wanted, it would cause unpredictable interrupt handling, and I can imagine that many drivers/devices will not like that.

The purpose is usually to spread the threads across several priorities, to create room for some RT-process to become more important than an IRQ that generates large latencies, and each RT-system designer shall divide the priorities different, due to different system requirements.

Kind Regards,

Remy

2007/12/20, Jaswinder Singh <[email protected]>:

Quoted 13 lines · Remy Bohmer
Quoted 2 lines

The RT-patch originally creates all its softirq-threads at priority 50.

Is it possible to run softirq-threads or IRQs as a non-realtime tasks in RT kernel.

If yes, then how.

Thank you,

Jaswinder Singh.

#11 lore raw

Re: [patch 3/3] Enable setting of IRQ-thread priorities from kernel cmdline. (repost:CC to LKML)

Hello Remy,

Quoted 1 line · Remy Bohmer

So, Is this a serious requirement? Should this be possible?

I have noticed this problem:

[email protected]:~# cat /proc/loadavgrt
1.00 1.00 1.00 0/52 1158
[email protected]:~# cat /proc/loadavg
0.00 0.00 0.02 1/52 1159
[email protected]:~#

So I am curious, if possible, user can switch softirq-threads or IRQs RT tasks to non-RT tasks for slow hardware or least important hardware for NON-RT tasks. So this will improve RT behaviour.

By default, all softirq-threads or IRQs will be RT task but if there is some option user can switch it to NON-RT task then it will be good.

Thank you,

Jaswinder Singh.

#12 lore raw

Re: [patch 3/3] Enable setting of IRQ-thread priorities from kernel cmdline. (repost:CC to LKML)

Quoted 2 lines

By default, all softirq-threads or IRQs will be RT task but if there is some option user can switch it to NON-RT task then it will be good.

Okay, understood.
I will think about how to add that too. But, probably we can add it seperately from this patchset.

Kind Regards,

Remy

2007/12/20, Jaswinder Singh <[email protected]>:

Quoted 23 lines

Hello Remy,

Quoted 1 line · Remy Bohmer

So, Is this a serious requirement? Should this be possible?

I have noticed this problem:

[email protected]:~# cat /proc/loadavgrt
1.00 1.00 1.00 0/52 1158
[email protected]:~# cat /proc/loadavg
0.00 0.00 0.02 1/52 1159
[email protected]:~#

So I am curious, if possible, user can switch softirq-threads or IRQs RT tasks to non-RT tasks for slow hardware or least important hardware for NON-RT tasks. So this will improve RT behaviour.

By default, all softirq-threads or IRQs will be RT task but if there is some option user can switch it to NON-RT task then it will be good.

Thank you,

Jaswinder Singh.

#13 lore raw

Re: [patch 3/3] Enable setting of IRQ-thread priorities from kernel cmdline. (repost:CC to LKML)

In reply to Jaswinder Singh
Quoted 10 lines · Jaswinder Singh
Quoted 1 line · Remy Bohmer

So, Is this a serious requirement? Should this be possible?

I have noticed this problem:

[email protected]:~# cat /proc/loadavgrt
1.00 1.00 1.00 0/52 1158
[email protected]:~# cat /proc/loadavg
0.00 0.00 0.02 1/52 1159
[email protected]:~#
Quoted 3 lines

So I am curious, if possible, user can switch softirq-threads or IRQs RT tasks to non-RT tasks for slow hardware or least important hardware for NON-RT tasks. So this will improve RT behaviour.

                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Why?

IMHO: Simply decrease the RT priority of less important IRQs or increase all other more important IRQs. IRQs are always more important than other processes in a system, also in non RT systems.

Juergen

Signature · 5 lines
Dipl.-Ing. Juergen Beisert | http://www.pengutronix.de
 Pengutronix - Linux Solutions for Science and Industry
    Handelsregister: Amtsgericht Hildesheim, HRA 2686
         Vertretung Sued/Muenchen, Germany
   Phone: +49-8766-939 228 |  Fax: +49-5121-206917-9
#14 lore raw

Re: [patch 3/3] Enable setting of IRQ-thread priorities from kernel cmdline. (repost:CC to LKML)

hello Juergen,

Quoted 11 lines · Juergen Beisert
Quoted 3 lines · Jaswinder Singh

So I am curious, if possible, user can switch softirq-threads or IRQs RT tasks to non-RT tasks for slow hardware or least important hardware for NON-RT tasks. So this will improve RT behaviour.

                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Why?

IMHO: Simply decrease the RT priority of less important IRQs or increase all other more important IRQs. IRQs are always more important than other processes in a system, also in non RT systems.

In RT Kernel we have :-
RT Tasks and Non-RT tasks.

So we can also support :-
RT softirq-threads/IRQs and non-RT softirq-threads/IRQs

So RT softirq-threads/IRQs for RT Tasks
and non-RT softirq-threads/IRQs for non-RT Tasks.

OR also remove Non-RT tasks from RT Kernel and simply decrease the RT priority of less important task as per your suggestions.

Thank you,

Jaswinder Singh.

Quoted 8 lines

Juergen
--
Dipl.-Ing. Juergen Beisert | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Vertretung Sued/Muenchen, Germany
Phone: +49-8766-939 228 | Fax: +49-5121-206917-9