[PATCH] libc: Add support for NUMA system calls.
Will Newton
will.newton at gmail.com
Wed Sep 15 15:15:28 UTC 2010
Add support for get_mempolicy(2), mbind(2), migrate_pages(2),
move_pages(2) and set_mempolicy(2).
These system calls can be used to manipulate the CPU and memory
allocation strategies of a process when used with a NUMA enabled
kernel. NUMA is used by a number of embedded SoCs to allow
processes to make use of low-latency on-chip memories.
The numaif.h header has been taken from the numactl/libnuma
package.
Signed-off-by: Will Newton <will.newton at imgtec.com>
---
libnuma doesn't work well with uClibc because it uses symbol versioning
which isn't supported by uClibc ldso. It's also a rather heavyweight solution
for the embedded space where typically that level of complexity is not
required.
This patch adds the system calls and header from libnuma as a lightweight
alternative.
Makefile.in | 4 ++
extra/Configs/Config.in | 13 ++++++++
include/numaif.h | 48 +++++++++++++++++++++++++++++
libc/sysdeps/linux/common/Makefile.in | 5 +++
libc/sysdeps/linux/common/get_mempolicy.c | 21 ++++++++++++
libc/sysdeps/linux/common/mbind.c | 23 ++++++++++++++
libc/sysdeps/linux/common/migrate_pages.c | 22 +++++++++++++
libc/sysdeps/linux/common/move_pages.c | 23 ++++++++++++++
libc/sysdeps/linux/common/set_mempolicy.c | 21 ++++++++++++
9 files changed, 180 insertions(+), 0 deletions(-)
create mode 100644 include/numaif.h
create mode 100644 libc/sysdeps/linux/common/get_mempolicy.c
create mode 100644 libc/sysdeps/linux/common/mbind.c
create mode 100644 libc/sysdeps/linux/common/migrate_pages.c
create mode 100644 libc/sysdeps/linux/common/move_pages.c
create mode 100644 libc/sysdeps/linux/common/set_mempolicy.c
diff --git a/Makefile.in b/Makefile.in
index 348bc0c..af37032 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -376,6 +376,10 @@ ifeq ($(UCLIBC_FORMAT_SHARED_FLAT),y)
fi; \
done
endif
+ifneq ($(UCLIBC_HAS_NUMA),y)
+ # Remove numaif.h since NUMA was disabled upon request
+ $(RM) $(PREFIX)$(DEVEL_PREFIX)include/numaif.h
+endif
# Installs run-time libraries
install_runtime: all | $(PREFIX)$(RUNTIME_PREFIX)$(MULTILIB_DIR)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index e8d522d..7518caf 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -1137,6 +1137,19 @@ config UCLIBC_HAS_CRYPT_STUB
config UCLIBC_HAS_CRYPT
def_bool y
depends on UCLIBC_HAS_CRYPT_IMPL || UCLIBC_HAS_CRYPT_STUB
+
+config UCLIBC_HAS_NUMA
+ bool "NUMA support"
+ default n
+ help
+ These functions allow tasks and memory to be moved between
+ different NUMA nodes. NUMA support must be enabled in the kernel
+ and the hardware must have more than one NUMA node for this
+ option to be useful.
+
+ get_mempolicy(), mbind(), migrate_pages(), move_pages(),
+ set_mempolicy()
+
endmenu
menuconfig UCLIBC_HAS_NETWORK_SUPPORT
diff --git a/include/numaif.h b/include/numaif.h
new file mode 100644
index 0000000..6aef7d5
--- /dev/null
+++ b/include/numaif.h
@@ -0,0 +1,48 @@
+#ifndef NUMAIF_H
+#define NUMAIF_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Kernel interface for NUMA API */
+
+/* System calls */
+extern long get_mempolicy(int *policy, const unsigned long *nmask,
+ unsigned long maxnode, void *addr, int flags);
+extern long mbind(void *start, unsigned long len, int mode,
+ const unsigned long *nmask, unsigned long maxnode, unsigned flags);
+extern long set_mempolicy(int mode, const unsigned long *nmask,
+ unsigned long maxnode);
+extern long migrate_pages(int pid, unsigned long maxnode,
+ const unsigned long *frommask,
+ const unsigned long *tomask);
+
+extern long move_pages(int pid, unsigned long count,
+ void **pages, const int *nodes, int *status, int flags);
+
+/* Policies */
+#define MPOL_DEFAULT 0
+#define MPOL_PREFERRED 1
+#define MPOL_BIND 2
+#define MPOL_INTERLEAVE 3
+
+#define MPOL_MAX MPOL_INTERLEAVE
+
+/* Flags for get_mem_policy */
+#define MPOL_F_NODE (1<<0) /* return next il node or node of address */
+ /* Warning: MPOL_F_NODE is unsupported and
+ subject to change. Don't use. */
+#define MPOL_F_ADDR (1<<1) /* look up vma using address */
+#define MPOL_F_MEMS_ALLOWED (1<<2) /* query nodes allowed in cpuset */
+
+/* Flags for mbind */
+#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */
+#define MPOL_MF_MOVE (1<<1) /* Move pages owned by this process to
conform to mapping */
+#define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mapping */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libc/sysdeps/linux/common/Makefile.in
b/libc/sysdeps/linux/common/Makefile.in
index 1711e80..f0f2b99 100644
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -102,6 +102,11 @@ endif
CSRC := $(filter-out $(libc_a_CSRC) $(notdir
$(libpthread_libc_OBJS:.o=.c)),$(CSRC))
SSRC := $(filter-out $(libc_a_SSRC) $(notdir
$(libpthread_libc_OBJS:.o=.S)),$(SSRC))
+ifneq ($(UCLIBC_HAS_NUMA),y)
+CSRC := $(filter-out get_mempolicy.c mbind.c migrate_pages.c move_pages.c \
+ set_mempolicy.c,$(CSRC))
+endif
+
# fails for some reason
ifneq ($(strip $(ARCH_OBJS)),)
CSRC := $(filter-out $(notdir $(ARCH_OBJS:.o=.c))
$(ARCH_OBJ_FILTEROUT),$(CSRC))
diff --git a/libc/sysdeps/linux/common/get_mempolicy.c
b/libc/sysdeps/linux/common/get_mempolicy.c
new file mode 100644
index 0000000..c0d2be5
--- /dev/null
+++ b/libc/sysdeps/linux/common/get_mempolicy.c
@@ -0,0 +1,21 @@
+/*
+ * get_mempolicy() for uClibc
+ *
+ * Copyright (C) 2010 Will Newton <will.newton at gmail.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+
+#ifdef __NR_get_mempolicy
+_syscall5(long, get_mempolicy, int *, __policy, const unsigned long *, __nmask,
+ unsigned long, __maxnode, void *, __addr, int, __flags)
+#else
+long get_mempolicy(int *__policy, const unsigned long *__nmask,
+ unsigned long __maxnode, void *__addr, int __flags)
+{
+ __set_errno(ENOSYS);
+ return -1;
+}
+#endif
diff --git a/libc/sysdeps/linux/common/mbind.c
b/libc/sysdeps/linux/common/mbind.c
new file mode 100644
index 0000000..2e77698
--- /dev/null
+++ b/libc/sysdeps/linux/common/mbind.c
@@ -0,0 +1,23 @@
+/*
+ * mbind() for uClibc
+ *
+ * Copyright (C) 2010 Will Newton <will.newton at gmail.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+
+#ifdef __NR_mbind
+_syscall6(long, mbind, void *, __start, unsigned long, __len,
+ int, __mode, const unsigned long *, __nmask,
+ unsigned long, __maxnode, unsigned int, __flags)
+#else
+long mbind(void * __start, unsigned long __len, int __mode,
+ const unsigned long * __nmask, unsigned long __maxnode,
+ unsigned int __flags)
+{
+ __set_errno(ENOSYS);
+ return -1;
+}
+#endif
diff --git a/libc/sysdeps/linux/common/migrate_pages.c
b/libc/sysdeps/linux/common/migrate_pages.c
new file mode 100644
index 0000000..cf3aa0d
--- /dev/null
+++ b/libc/sysdeps/linux/common/migrate_pages.c
@@ -0,0 +1,22 @@
+/*
+ * migrate_pages() for uClibc
+ *
+ * Copyright (C) 2010 Will Newton <will.newton at gmail.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+
+#ifdef __NR_migrate_pages
+_syscall4(long, migrate_pages, int, __pid, unsigned long, __maxnode,
+ const unsigned long *, __frommask, const unsigned long *, __tomask)
+#else
+long migrate_pages(int __pid, unsigned long __maxnode,
+ const unsigned long * __frommask,
+ const unsigned long * __tomask)
+{
+ __set_errno(ENOSYS);
+ return -1;
+}
+#endif
diff --git a/libc/sysdeps/linux/common/move_pages.c
b/libc/sysdeps/linux/common/move_pages.c
new file mode 100644
index 0000000..e8d99b0
--- /dev/null
+++ b/libc/sysdeps/linux/common/move_pages.c
@@ -0,0 +1,23 @@
+/*
+ * move_pages() for uClibc
+ *
+ * Copyright (C) 2010 Will Newton <will.newton at gmail.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+
+#ifdef __NR_move_pages
+_syscall6(long, move_pages, int, __pid, unsigned long, __count,
+ void **, __pages, const int *, __nodes, int *, __status,
+ int, __flags)
+#else
+long move_pages(int __pid, unsigned long __count,
+ void ** __pages, const int * __nodes, int * __status,
+ int __flags)
+{
+ __set_errno(ENOSYS);
+ return -1;
+}
+#endif
diff --git a/libc/sysdeps/linux/common/set_mempolicy.c
b/libc/sysdeps/linux/common/set_mempolicy.c
new file mode 100644
index 0000000..c625041
--- /dev/null
+++ b/libc/sysdeps/linux/common/set_mempolicy.c
@@ -0,0 +1,21 @@
+/*
+ * set_mempolicy() for uClibc
+ *
+ * Copyright (C) 2010 Will Newton <will.newton at gmail.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+
+#ifdef __NR_set_mempolicy
+_syscall3(long, set_mempolicy, int , __mode, const unsigned long *, __nmask,
+ unsigned long, __maxnode)
+#else
+long set_mempolicy(int __mode, const unsigned long *__nmask,
+ unsigned long __maxnode)
+{
+ __set_errno(ENOSYS);
+ return -1;
+}
+#endif
--
1.7.2.2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-libc-Add-support-for-NUMA-system-calls.patch
Type: text/x-patch
Size: 9065 bytes
Desc: not available
URL: <http://lists.busybox.net/pipermail/uclibc/attachments/20100915/67e3e7f0/attachment-0001.bin>
More information about the uClibc
mailing list