From fe4de567b50f7ca317b16f69b7b3a7de693025af Mon Sep 17 00:00:00 2001 From: attilio Date: Thu, 5 May 2011 14:39:14 +0000 Subject: Commit the support for removing cpumask_t and replacing it directly with cpuset_t objects. That is going to offer the underlying support for a simple bump of MAXCPU and then support for number of cpus > 32 (as it is today). Right now, cpumask_t is an int, 32 bits on all our supported architecture. cpumask_t on the other side is implemented as an array of longs, and easilly extendible by definition. The architectures touched by this commit are the following: - amd64 - i386 - pc98 - arm - ia64 - XEN while the others are still missing. Userland is believed to be fully converted with the changes contained here. Some technical notes: - This commit may be considered an ABI nop for all the architectures different from amd64 and ia64 (and sparc64 in the future) - per-cpu members, which are now converted to cpuset_t, needs to be accessed avoiding migration, because the size of cpuset_t should be considered unknown - size of cpuset_t objects is different from kernel and userland (this is primirally done in order to leave some more space in userland to cope with KBI extensions). If you need to access kernel cpuset_t from the userland please refer to example in this patch on how to do that correctly (kgdb may be a good source, for example). - Support for other architectures is going to be added soon - Only MAXCPU for amd64 is bumped now The patch has been tested by sbruno and Nicholas Esborn on opteron 4 x 12 pack CPUs. More testing on big SMP is expected to came soon. pluknet tested the patch with his 8-ways on both amd64 and i386. Tested by: pluknet, sbruno, gianni, Nicholas Esborn Reviewed by: jeff, jhb, sbruno --- sys/kern/kern_cpuset.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'sys/kern/kern_cpuset.c') diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index bf9eac7..9ed19d4 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -617,6 +617,49 @@ out: } /* + * Calculate the ffs() of the cpuset. + */ +int +cpusetobj_ffs(const cpuset_t *set) +{ + size_t i; + int cbit; + + cbit = 0; + for (i = 0; i < _NCPUWORDS; i++) { + if (set->__bits[i] != 0) { + cbit = ffsl(set->__bits[i]); + cbit += i * _NCPUBITS; + break; + } + } + return (cbit); +} + +/* + * Return a string representing a valid layout for a cpuset_t object. + * It expects an incoming buffer at least sized as CPUSETBUFSIZ. + */ +char * +cpusetobj_strprint(char *buf, const cpuset_t *set) +{ + char *tbuf; + size_t i, bytesp, bufsiz; + + tbuf = buf; + bytesp = 0; + bufsiz = CPUSETBUFSIZ; + + for (i = 0; i < (_NCPUWORDS - 1); i++) { + bytesp = snprintf(tbuf, bufsiz, "%lx, ", set->__bits[i]); + bufsiz -= bytesp; + tbuf += bytesp; + } + snprintf(tbuf, bufsiz, "%lx", set->__bits[_NCPUWORDS - 1]); + return (buf); +} + +/* * Apply an anonymous mask to a single thread. */ int @@ -754,11 +797,10 @@ cpuset_init(void *arg) { cpuset_t mask; - CPU_ZERO(&mask); #ifdef SMP - mask.__bits[0] = all_cpus; + mask = all_cpus; #else - mask.__bits[0] = 1; + CPU_SETOF(0, &mask); #endif if (cpuset_modify(cpuset_zero, &mask)) panic("Can't set initial cpuset mask.\n"); -- cgit v1.1 From 9309cc63ed0edb010fd6cb468850c07a474310f5 Mon Sep 17 00:00:00 2001 From: attilio Date: Sat, 14 May 2011 18:22:08 +0000 Subject: Simplify the code here. Submitted by: jhb --- sys/kern/kern_cpuset.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sys/kern/kern_cpuset.c') diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index 9ed19d4..d604c59 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -797,11 +797,7 @@ cpuset_init(void *arg) { cpuset_t mask; -#ifdef SMP mask = all_cpus; -#else - CPU_SETOF(0, &mask); -#endif if (cpuset_modify(cpuset_zero, &mask)) panic("Can't set initial cpuset mask.\n"); cpuset_zero->cs_flags |= CPU_SET_RDONLY; -- cgit v1.1 From c5a5c48e70de18e3c28cb0005fc2d9ab6a83a8f7 Mon Sep 17 00:00:00 2001 From: attilio Date: Sat, 14 May 2011 19:36:12 +0000 Subject: Fix a longstanding bug where only the first part of the cpumask was correctly set full. Submitted by: anonymous --- sys/kern/kern_cpuset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys/kern/kern_cpuset.c') diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index d604c59..5d058e6 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -719,7 +719,7 @@ cpuset_thread0(void) * cpuset_create() due to NULL parent. */ set = uma_zalloc(cpuset_zone, M_WAITOK | M_ZERO); - set->cs_mask.__bits[0] = -1; + CPU_FILL(&set->cs_mask); LIST_INIT(&set->cs_children); LIST_INSERT_HEAD(&cpuset_ids, set, cs_link); set->cs_ref = 1; -- cgit v1.1 From 08bcb681d2e1e3a0707624ad288cb81cd79bed89 Mon Sep 17 00:00:00 2001 From: attilio Date: Sun, 22 May 2011 20:29:47 +0000 Subject: Make cpusetobj_strprint() prepare the string in order to print the least significant cpuset_t word at the outmost right part of the string (more far from the beginning of it). This follows the natural build of bits rappresentation in the words. --- sys/kern/kern_cpuset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys/kern/kern_cpuset.c') diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index 5d058e6..3b2c653 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -650,12 +650,12 @@ cpusetobj_strprint(char *buf, const cpuset_t *set) bytesp = 0; bufsiz = CPUSETBUFSIZ; - for (i = 0; i < (_NCPUWORDS - 1); i++) { + for (i = _NCPUWORDS - 1; i > 0; i--) { bytesp = snprintf(tbuf, bufsiz, "%lx, ", set->__bits[i]); bufsiz -= bytesp; tbuf += bytesp; } - snprintf(tbuf, bufsiz, "%lx", set->__bits[_NCPUWORDS - 1]); + snprintf(tbuf, bufsiz, "%lx", set->__bits[0]); return (buf); } -- cgit v1.1 From 6d7371f9503a4d916171e610f74e6bcf20071227 Mon Sep 17 00:00:00 2001 From: attilio Date: Mon, 23 May 2011 01:17:30 +0000 Subject: MFC --- sys/kern/kern_cpuset.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'sys/kern/kern_cpuset.c') diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index 3b2c653..5ca3be2 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -660,6 +661,41 @@ cpusetobj_strprint(char *buf, const cpuset_t *set) } /* + * Build a valid cpuset_t object from a string representation. + * It expects an incoming buffer at least sized as CPUSETBUFSIZ. + */ +int +cpusetobj_strscan(cpuset_t *set, const char *buf) +{ + u_int nwords; + int i; + + if (strlen(buf) > CPUSETBUFSIZ - 1) + return (-1); + + /* Allow to pass a shorter version of the mask when necessary. */ + nwords = 1; + for (i = 0; buf[i] != '\0'; i++) + if (buf[i] == ',') + nwords++; + if (nwords > _NCPUWORDS) + return (-1); + + CPU_ZERO(set); + for (i = nwords - 1; i > 0; i--) { + if (!sscanf(buf, "%lx, ", &set->__bits[i])) + return (-1); + buf = strstr(buf, " "); + if (buf == NULL) + return (-1); + buf++; + } + if (!sscanf(buf, "%lx", &set->__bits[0])) + return (-1); + return (0); +} + +/* * Apply an anonymous mask to a single thread. */ int -- cgit v1.1 From 66305282ac742acac807ca249a5265954a288f53 Mon Sep 17 00:00:00 2001 From: attilio Date: Mon, 23 May 2011 23:50:21 +0000 Subject: Revert a patch that unvolountary sneaked in while I was MFCing. --- sys/kern/kern_cpuset.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'sys/kern/kern_cpuset.c') diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index 5ca3be2..3b2c653 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -661,41 +660,6 @@ cpusetobj_strprint(char *buf, const cpuset_t *set) } /* - * Build a valid cpuset_t object from a string representation. - * It expects an incoming buffer at least sized as CPUSETBUFSIZ. - */ -int -cpusetobj_strscan(cpuset_t *set, const char *buf) -{ - u_int nwords; - int i; - - if (strlen(buf) > CPUSETBUFSIZ - 1) - return (-1); - - /* Allow to pass a shorter version of the mask when necessary. */ - nwords = 1; - for (i = 0; buf[i] != '\0'; i++) - if (buf[i] == ',') - nwords++; - if (nwords > _NCPUWORDS) - return (-1); - - CPU_ZERO(set); - for (i = nwords - 1; i > 0; i--) { - if (!sscanf(buf, "%lx, ", &set->__bits[i])) - return (-1); - buf = strstr(buf, " "); - if (buf == NULL) - return (-1); - buf++; - } - if (!sscanf(buf, "%lx", &set->__bits[0])) - return (-1); - return (0); -} - -/* * Apply an anonymous mask to a single thread. */ int -- cgit v1.1 From 066c7ac96c87ad7070c7f2469bab58ef10a9f636 Mon Sep 17 00:00:00 2001 From: attilio Date: Tue, 31 May 2011 20:23:33 +0000 Subject: Revert a change that crept in during MFC. --- sys/kern/kern_cpuset.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'sys/kern/kern_cpuset.c') diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index 5ca3be2..3b2c653 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -661,41 +660,6 @@ cpusetobj_strprint(char *buf, const cpuset_t *set) } /* - * Build a valid cpuset_t object from a string representation. - * It expects an incoming buffer at least sized as CPUSETBUFSIZ. - */ -int -cpusetobj_strscan(cpuset_t *set, const char *buf) -{ - u_int nwords; - int i; - - if (strlen(buf) > CPUSETBUFSIZ - 1) - return (-1); - - /* Allow to pass a shorter version of the mask when necessary. */ - nwords = 1; - for (i = 0; buf[i] != '\0'; i++) - if (buf[i] == ',') - nwords++; - if (nwords > _NCPUWORDS) - return (-1); - - CPU_ZERO(set); - for (i = nwords - 1; i > 0; i--) { - if (!sscanf(buf, "%lx, ", &set->__bits[i])) - return (-1); - buf = strstr(buf, " "); - if (buf == NULL) - return (-1); - buf++; - } - if (!sscanf(buf, "%lx", &set->__bits[0])) - return (-1); - return (0); -} - -/* * Apply an anonymous mask to a single thread. */ int -- cgit v1.1 From a924571ff72281d66b56beff01ea2b9ed8de6961 Mon Sep 17 00:00:00 2001 From: attilio Date: Tue, 31 May 2011 20:48:58 +0000 Subject: Fix KTR_CPUMASK in order to accept a string representing a cpuset_t. This introduce all the underlying support for making this possible (via the function cpusetobj_strscan() and keeps ktr_cpumask exported. sparc64 implements its own assembly primitives for tracing events and needs to properly check it. Anyway the sparc64 logic is not implemented yet due to lack of knowledge (by me) and time (by marius), but it is just a matter of using ktr_cpumask when possible. Tested and fixed by: pluknet Reviewed by: marius --- sys/kern/kern_cpuset.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'sys/kern/kern_cpuset.c') diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index 3b2c653..e1f2801 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -660,6 +661,43 @@ cpusetobj_strprint(char *buf, const cpuset_t *set) } /* + * Build a valid cpuset_t object from a string representation. + * It expects an incoming buffer at least sized as CPUSETBUFSIZ. + */ +int +cpusetobj_strscan(cpuset_t *set, const char *buf) +{ + u_int nwords; + int i, ret; + + if (strlen(buf) > CPUSETBUFSIZ - 1) + return (-1); + + /* Allow to pass a shorter version of the mask when necessary. */ + nwords = 1; + for (i = 0; buf[i] != '\0'; i++) + if (buf[i] == ',') + nwords++; + if (nwords > _NCPUWORDS) + return (-1); + + CPU_ZERO(set); + for (i = nwords - 1; i > 0; i--) { + ret = sscanf(buf, "%lx, ", &set->__bits[i]); + if (ret == 0 || ret == -1) + return (-1); + buf = strstr(buf, " "); + if (buf == NULL) + return (-1); + buf++; + } + ret = sscanf(buf, "%lx", &set->__bits[0]); + if (ret == 0 || ret == -1) + return (-1); + return (0); +} + +/* * Apply an anonymous mask to a single thread. */ int -- cgit v1.1