From: Ammar Faizi <[email protected]>
To: Jens Axboe <[email protected]>,
Pavel Begunkov <[email protected]>,
io-uring Mailing List <[email protected]>
Cc: Bedirhan KURT <[email protected]>,
Louvian Lyndal <[email protected]>,
Ammar Faizi <[email protected]>
Subject: [PATCH v3 liburing 2/3] Add nolibc build support
Date: Sun, 10 Oct 2021 20:53:37 +0700 [thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
Create `src/nolibc.c` to provide libc functions like `memset()`,
`malloc()` and `free()`. Only build this file when we build liburing
without libc.
Add `get_page_size()` function to get the page size. When we build
with libc, it uses `sysconf(_SC_PAGESIZE)`, otherwise it uses arch
dependent implementation function that we provide at `src/arch` dir.
Add conditional preprocessor in `src/syscall.h` to use arch dependent
syscalls written in Assembly when we build liburing without libc.
Extra notes for tests:
1) Functions in `src/syscall.c` require libc to work.
2) Tests require functions in `src/syscall.c`.
So we build `src/syscall.c` manually from the test's Makefile.
The Makefile in `src/` dir still builds `src/syscall.c` when we
build liburing with libc.
Link: https://github.com/axboe/liburing/issues/443
Reviewed-by: Jens Axboe <[email protected]>
Signed-off-by: Ammar Faizi <[email protected]>
---
src/lib.h | 44 +++++++++++++++++++++++++++++++
src/nolibc.c | 48 ++++++++++++++++++++++++++++++++++
src/queue.c | 14 +++-------
src/register.c | 12 +++------
src/setup.c | 17 +++---------
src/syscall.c | 11 +++++++-
src/syscall.h | 71 +++++++++++++++++++++++++++++++++++++++-----------
test/Makefile | 19 +++++++++++---
8 files changed, 183 insertions(+), 53 deletions(-)
create mode 100644 src/lib.h
create mode 100644 src/nolibc.c
diff --git a/src/lib.h b/src/lib.h
new file mode 100644
index 0000000..58d91be
--- /dev/null
+++ b/src/lib.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef LIBURING_LIB_H
+#define LIBURING_LIB_H
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef CONFIG_NOLIBC
+# if defined(__x86_64__) || defined(__i386__)
+# include "arch/x86/lib.h"
+# else
+# error "This arch doesn't support building liburing without libc"
+# endif
+#endif
+
+#ifndef offsetof
+# define offsetof(TYPE, FIELD) ((size_t) &((TYPE *)0)->FIELD)
+#endif
+
+#ifndef container_of
+# define container_of(PTR, TYPE, FIELD) ({ \
+ __typeof__(((TYPE *)0)->FIELD) *__FIELD_PTR = (PTR); \
+ (TYPE *)((char *) __FIELD_PTR - offsetof(TYPE, FIELD)); \
+})
+#endif
+
+
+static inline long get_page_size(void)
+{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_get_page_size();
+#else
+ long page_size;
+
+ page_size = sysconf(_SC_PAGESIZE);
+ if (page_size < 0)
+ page_size = 4096;
+
+ return page_size;
+#endif
+}
+
+#endif /* #ifndef LIBURING_LIB_H */
diff --git a/src/nolibc.c b/src/nolibc.c
new file mode 100644
index 0000000..5582ca0
--- /dev/null
+++ b/src/nolibc.c
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: MIT */
+
+#ifndef CONFIG_NOLIBC
+# error "This file should only be compiled for no libc build"
+#endif
+
+#include "lib.h"
+#include "syscall.h"
+
+void *memset(void *s, int c, size_t n)
+{
+ size_t i;
+ unsigned char *p = s;
+
+ for (i = 0; i < n; i++)
+ p[i] = (unsigned char) c;
+
+ return s;
+}
+
+struct uring_heap {
+ size_t len;
+ char user_p[];
+};
+
+void *malloc(size_t len)
+{
+ struct uring_heap *heap;
+
+ heap = uring_mmap(NULL, sizeof(*heap) + len, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (IS_ERR(heap))
+ return NULL;
+
+ heap->len = sizeof(*heap) + len;
+ return heap->user_p;
+}
+
+void free(void *p)
+{
+ struct uring_heap *heap;
+
+ if (uring_unlikely(!p))
+ return;
+
+ heap = container_of(p, struct uring_heap, user_p);
+ uring_munmap(heap, heap->len);
+}
diff --git a/src/queue.c b/src/queue.c
index 9af29d5..eb0c736 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -1,19 +1,11 @@
/* SPDX-License-Identifier: MIT */
#define _POSIX_C_SOURCE 200112L
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdbool.h>
-
+#include "lib.h"
+#include "syscall.h"
+#include "liburing.h"
#include "liburing/compat.h"
#include "liburing/io_uring.h"
-#include "liburing.h"
-#include "liburing/barrier.h"
-
-#include "syscall.h"
/*
* Returns true if we're not using SQ thread (thus nobody submits but us)
diff --git a/src/register.c b/src/register.c
index 074223f..1f2c409 100644
--- a/src/register.c
+++ b/src/register.c
@@ -1,18 +1,12 @@
/* SPDX-License-Identifier: MIT */
#define _POSIX_C_SOURCE 200112L
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <unistd.h>
-#include <string.h>
-
+#include "lib.h"
+#include "syscall.h"
+#include "liburing.h"
#include "liburing/compat.h"
#include "liburing/io_uring.h"
-#include "liburing.h"
-#include "syscall.h"
int io_uring_register_buffers_update_tag(struct io_uring *ring, unsigned off,
const struct iovec *iovecs,
diff --git a/src/setup.c b/src/setup.c
index 4f006de..5543468 100644
--- a/src/setup.c
+++ b/src/setup.c
@@ -1,18 +1,12 @@
/* SPDX-License-Identifier: MIT */
#define _DEFAULT_SOURCE
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <signal.h>
-
+#include "lib.h"
+#include "syscall.h"
+#include "liburing.h"
#include "liburing/compat.h"
#include "liburing/io_uring.h"
-#include "liburing.h"
-#include "syscall.h"
static void io_uring_unmap_rings(struct io_uring_sq *sq, struct io_uring_cq *cq)
{
@@ -336,10 +330,7 @@ ssize_t io_uring_mlock_size_params(unsigned entries, struct io_uring_params *p)
cq_entries = 2 * entries;
}
- page_size = sysconf(_SC_PAGESIZE);
- if (page_size < 0)
- page_size = 4096;
-
+ page_size = get_page_size();
return rings_size(entries, cq_entries, page_size);
}
diff --git a/src/syscall.c b/src/syscall.c
index 5923fbb..4e28e25 100644
--- a/src/syscall.c
+++ b/src/syscall.c
@@ -1,6 +1,16 @@
/* SPDX-License-Identifier: MIT */
#define _DEFAULT_SOURCE
+/*
+ * Functions in this file require libc, only build them when we use libc.
+ *
+ * Note:
+ * liburing's tests still need these functions.
+ */
+#if defined(CONFIG_NOLIBC) && !defined(LIBURING_BUILD_TEST)
+# error "This file should only be compiled for libc build, or for liburing tests"
+#endif
+
/*
* Will go away once libc support is there
*/
@@ -11,7 +21,6 @@
#include "liburing/io_uring.h"
#include "syscall.h"
-
int __sys_io_uring_register(int fd, unsigned opcode, const void *arg,
unsigned nr_args)
{
diff --git a/src/syscall.h b/src/syscall.h
index 9eff968..4b336f1 100644
--- a/src/syscall.h
+++ b/src/syscall.h
@@ -29,13 +29,13 @@
# endif
#elif defined __mips__
# ifndef __NR_io_uring_setup
-# define __NR_io_uring_setup (__NR_Linux + 425)
+# define __NR_io_uring_setup (__NR_Linux + 425)
# endif
# ifndef __NR_io_uring_enter
-# define __NR_io_uring_enter (__NR_Linux + 426)
+# define __NR_io_uring_enter (__NR_Linux + 426)
# endif
# ifndef __NR_io_uring_register
-# define __NR_io_uring_register (__NR_Linux + 427)
+# define __NR_io_uring_register (__NR_Linux + 427)
# endif
#else /* !__alpha__ and !__mips__ */
# ifndef __NR_io_uring_setup
@@ -49,9 +49,22 @@
# endif
#endif
-
+/*
+ * Don't put this below the #include "arch/$arch/syscall.h", that
+ * file may need it.
+ */
struct io_uring_params;
+
+#ifdef CONFIG_NOLIBC
+# if defined(__x86_64__) || defined(__i386__)
+# include "arch/x86/syscall.h"
+# else
+# error "This arch doesn't support building liburing without libc"
+# endif
+#endif
+
+
/*
* System calls
*/
@@ -68,12 +81,12 @@ static inline void *ERR_PTR(intptr_t n)
return (void *) n;
}
-static inline intptr_t PTR_ERR(void *ptr)
+static inline intptr_t PTR_ERR(const void *ptr)
{
return (intptr_t) ptr;
}
-static inline bool IS_ERR(void *ptr)
+static inline bool IS_ERR(const void *ptr)
{
return uring_unlikely((uintptr_t) ptr >= (uintptr_t) -4095UL);
}
@@ -81,30 +94,40 @@ static inline bool IS_ERR(void *ptr)
static inline int ____sys_io_uring_register(int fd, unsigned opcode,
const void *arg, unsigned nr_args)
{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_io_uring_register(fd, opcode, arg, nr_args);
+#else
int ret;
-
ret = syscall(__NR_io_uring_register, fd, opcode, arg, nr_args);
return (ret < 0) ? -errno : ret;
+#endif
}
static inline int ____sys_io_uring_setup(unsigned entries,
struct io_uring_params *p)
{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_io_uring_setup(entries, p);
+#else
int ret;
-
ret = syscall(__NR_io_uring_setup, entries, p);
return (ret < 0) ? -errno : ret;
+#endif
}
static inline int ____sys_io_uring_enter2(int fd, unsigned to_submit,
unsigned min_complete, unsigned flags,
sigset_t *sig, int sz)
{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_io_uring_enter(fd, to_submit, min_complete, flags,
+ sig, sz);
+#else
int ret;
-
ret = syscall(__NR_io_uring_enter, fd, to_submit, min_complete, flags,
sig, sz);
return (ret < 0) ? -errno : ret;
+#endif
}
static inline int ____sys_io_uring_enter(int fd, unsigned to_submit,
@@ -118,50 +141,68 @@ static inline int ____sys_io_uring_enter(int fd, unsigned to_submit,
static inline void *uring_mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset)
{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_mmap(addr, length, prot, flags, fd, offset);
+#else
void *ret;
-
ret = mmap(addr, length, prot, flags, fd, offset);
return (ret == MAP_FAILED) ? ERR_PTR(-errno) : ret;
+#endif
}
static inline int uring_munmap(void *addr, size_t length)
{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_munmap(addr, length);
+#else
int ret;
-
ret = munmap(addr, length);
return (ret < 0) ? -errno : ret;
+#endif
}
static inline int uring_madvise(void *addr, size_t length, int advice)
{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_madvise(addr, length, advice);
+#else
int ret;
-
ret = madvise(addr, length, advice);
return (ret < 0) ? -errno : ret;
+#endif
}
static inline int uring_getrlimit(int resource, struct rlimit *rlim)
{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_getrlimit(resource, rlim);
+#else
int ret;
-
ret = getrlimit(resource, rlim);
return (ret < 0) ? -errno : ret;
+#endif
}
static inline int uring_setrlimit(int resource, const struct rlimit *rlim)
{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_setrlimit(resource, rlim);
+#else
int ret;
-
ret = setrlimit(resource, rlim);
return (ret < 0) ? -errno : ret;
+#endif
}
static inline int uring_close(int fd)
{
+#ifdef CONFIG_NOLIBC
+ return __arch_impl_close(fd);
+#else
int ret;
-
ret = close(fd);
return (ret < 0) ? -errno : ret;
+#endif
}
#endif
diff --git a/test/Makefile b/test/Makefile
index 2936469..1a10a24 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -21,8 +21,8 @@ ifdef CONFIG_HAVE_ARRAY_BOUNDS
endif
CXXFLAGS ?= $(CFLAGS)
-override CFLAGS += $(XCFLAGS)
-override CXXFLAGS += $(XCFLAGS) -std=c++11
+override CFLAGS += $(XCFLAGS) -DLIBURING_BUILD_TEST
+override CXXFLAGS += $(XCFLAGS) -std=c++11 -DLIBURING_BUILD_TEST
LDFLAGS ?=
override LDFLAGS += -L../src/ -luring
@@ -153,11 +153,22 @@ test_targets += sq-full-cpp
endif
all_targets += sq-full-cpp
-helpers = helpers.o
+#
+# Build ../src/syscall.c manually from test's Makefile to support
+# liburing nolibc.
+#
+# Functions in ../src/syscall.c require libc to work with, if we
+# build liburing without libc, we don't have those functions
+# in liburing.a. So build it manually here.
+#
+helpers = helpers.o ../src/syscall.o
all: ${helpers} $(test_targets)
-helpers.o: helpers.c helpers.c
+../src/syscall.o: ../src/syscall.c
+ $(QUIET_CC)$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
+
+helpers.o: helpers.c
$(QUIET_CC)$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
%: %.c ${helpers} helpers.h
--
2.30.2
next prev parent reply other threads:[~2021-10-10 13:53 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-10 13:53 [PATCHSET v3 liburing 0/3] Add nolibc support for x86-64 arch Ammar Faizi
2021-10-10 13:53 ` [PATCH v3 liburing 1/3] Add arch dependent directory and files Ammar Faizi
2021-10-10 13:53 ` Ammar Faizi [this message]
2021-10-10 13:53 ` [PATCH v3 liburing 3/3] configure: Add `CONFIG_NOLIBC` variable and macro Ammar Faizi
2021-10-10 15:11 ` [PATCHSET v3 liburing 0/3] Add nolibc support for x86-64 arch Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211010135338.397115-3-ammar.faizi@students.amikom.ac.id \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox