* [PATCH v4 4/7] futex: Create set_robust_list2
From: André Almeida @ 2025-05-20 20:48 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Peter Zijlstra, Darren Hart,
Davidlohr Bueso, Shuah Khan, Arnd Bergmann,
Sebastian Andrzej Siewior, Waiman Long
Cc: linux-kernel, linux-kselftest, linux-api, André Almeida
In-Reply-To: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com>
Create a new robust_list() syscall. The current syscall can't be
expanded to cover the following use case, so a new one is needed. This
new syscall allows users to set multiple robust lists per process and to
have either 32bit or 64bit pointers in the list.
* Interface
This is the proposed interface:
long set_robust_list2(void *head, int index, unsigned int flags)
`head` is the head of the userspace struct robust_list_head, just as old
set_robust_list(). It needs to be a void pointer since it can point to a
normal robust_list_head or a compat_robust_list_head.
`flags` can be used for defining the list type:
enum robust_list_type {
ROBUST_LIST_32BIT,
ROBUST_LIST_64BIT,
};
`index` is the index in the internal robust_list's linked list (the
naming starts to get confusing, I reckon). If `index == -1`, that means
that user wants to set a new robust_list, and the kernel will append it
in the end of the list, assign a new index and return this index to the
user. If `index >= 0`, that means that user wants to re-set `*head` of
an already existing list (similarly to what happens when you call
set_robust_list() twice with different `*head`).
If `index` is out of range, or it points to a non-existing robust_list,
or if the internal list is full, an error is returned.
Unaligned `head` addresses are refused by the kernel with -EINVAL.
User cannot remove lists.
* Implementation
The old syscall's set/get_robust_list() are converted to use the linked
list as well. When using only the old syscalls user shouldn't any
difference as the internal code will handle the linked list insertion as
usual. When mixing old and new interfaces users should be aware that one
of the elements of the list was created by another syscall and they
should have special care handling this element index.
On exit, the linked list is parsed and all robust lists regardless of
which interface it was used to create them are handled.
Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
include/linux/futex.h | 5 +-
include/linux/sched.h | 5 +-
include/uapi/asm-generic/unistd.h | 2 +
include/uapi/linux/futex.h | 24 +++++++++
kernel/futex/core.c | 111 ++++++++++++++++++++++++++++++--------
kernel/futex/futex.h | 5 ++
kernel/futex/syscalls.c | 81 ++++++++++++++++++++++++++--
7 files changed, 204 insertions(+), 29 deletions(-)
diff --git a/include/linux/futex.h b/include/linux/futex.h
index cd7c5d12c846566c56f3f3ea74b95e437a6e8193..7721629926535c775bd7b05b5283a3d0b51262d6 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -75,10 +75,11 @@ enum {
static inline void futex_init_task(struct task_struct *tsk)
{
- tsk->robust_list = NULL;
+ tsk->robust_list_index = -1;
#ifdef CONFIG_COMPAT
- tsk->compat_robust_list = NULL;
+ tsk->compat_robust_list_index = -1;
#endif
+ INIT_LIST_HEAD(&tsk->robust_list2);
INIT_LIST_HEAD(&tsk->pi_state_list);
tsk->pi_state_cache = NULL;
tsk->futex_state = FUTEX_STATE_OK;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 51e5d05a9fcd407dcd53b7b7cb8c59783660a826..a37c55cf0a4d942ec1fbedb8bcd4be5a3ebb20bb 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1322,10 +1322,11 @@ struct task_struct {
u32 rmid;
#endif
#ifdef CONFIG_FUTEX
- struct robust_list_head __user *robust_list;
+ int robust_list_index;
#ifdef CONFIG_COMPAT
- struct robust_list_head32 __user *compat_robust_list;
+ int compat_robust_list_index;
#endif
+ struct list_head robust_list2;
struct list_head pi_state_list;
struct futex_pi_state *pi_state_cache;
struct mutex futex_exit_mutex;
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 2892a45023af6d3eb941623d4fed04841ab07e02..ebe68c2c88eb5390dda184ce9268a8d3a606c9e5 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -852,6 +852,8 @@ __SYSCALL(__NR_removexattrat, sys_removexattrat)
#define __NR_open_tree_attr 467
__SYSCALL(__NR_open_tree_attr, sys_open_tree_attr)
+#define __NR_set_robust_list2 467
+
#undef __NR_syscalls
#define __NR_syscalls 468
diff --git a/include/uapi/linux/futex.h b/include/uapi/linux/futex.h
index 7e2744ec89336a260e89883e95222eda199eeb7f..cbd321eca03afb6bdcf47e9534761d82f9de7e43 100644
--- a/include/uapi/linux/futex.h
+++ b/include/uapi/linux/futex.h
@@ -153,6 +153,30 @@ struct robust_list_head {
struct robust_list __user *list_op_pending;
};
+#define ROBUST_LISTS_PER_TASK 10
+
+enum robust_list2_type {
+ ROBUST_LIST_32BIT,
+ ROBUST_LIST_64BIT,
+};
+
+#define ROBUST_LIST_TYPE_MASK (ROBUST_LIST_32BIT | ROBUST_LIST_64BIT)
+
+/*
+ * This is an entry of a linked list of robust lists.
+ *
+ * @head: can point to a 64bit list or a 32bit list
+ * @list_type: determine the size of the futex pointers in the list
+ * @index: the index of this entry in the list
+ * @list: linked list element
+ */
+struct robust_list2_entry {
+ void __user *head;
+ enum robust_list2_type list_type;
+ unsigned int index;
+ struct list_head list;
+};
+
/*
* Are there any waiters for this robust futex:
*/
diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index 8640770aadc611b7341a3abb41bdb740e6394479..49b3bc592948a811f995017027f33ad8f285531f 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -1151,9 +1151,9 @@ static inline int fetch_robust_entry(struct robust_list __user **entry,
*
* We silently return on any sign of list-walking problem.
*/
-static void exit_robust_list64(struct task_struct *curr)
+static void exit_robust_list64(struct task_struct *curr,
+ struct robust_list_head __user *head)
{
- struct robust_list_head __user *head = curr->robust_list;
struct robust_list __user *entry, *next_entry, *pending;
unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
unsigned int next_pi;
@@ -1213,7 +1213,8 @@ static void exit_robust_list64(struct task_struct *curr)
}
}
#else
-static void exit_robust_list64(struct task_struct *curr)
+static void exit_robust_list64(struct task_struct *curr,
+ struct robust_list_head __user *head)
{
pr_warn("32bit kernel should not allow ROBUST_LIST_64BIT");
}
@@ -1250,9 +1251,9 @@ fetch_robust_entry32(u32 *uentry, struct robust_list __user **entry,
*
* We silently return on any sign of list-walking problem.
*/
-static void exit_robust_list32(struct task_struct *curr)
+static void exit_robust_list32(struct task_struct *curr,
+ struct robust_list_head32 __user *head)
{
- struct robust_list_head32 __user *head = curr->compat_robust_list;
struct robust_list __user *entry, *next_entry, *pending;
unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
unsigned int next_pi;
@@ -1318,6 +1319,70 @@ static void exit_robust_list32(struct task_struct *curr)
}
}
+long do_set_robust_list2(struct robust_list_head __user *head,
+ int index, unsigned int type)
+{
+ struct list_head *list2 = ¤t->robust_list2;
+ struct robust_list2_entry *prev, *new = NULL;
+
+ if (index == -1) {
+ if (list_empty(list2)) {
+ index = 0;
+ } else {
+ prev = list_last_entry(list2, struct robust_list2_entry, list);
+ index = prev->index + 1;
+ }
+
+ if (index >= ROBUST_LISTS_PER_TASK)
+ return -EINVAL;
+
+ new = kmalloc(sizeof(struct robust_list2_entry), GFP_KERNEL);
+ if (!new)
+ return -ENOMEM;
+
+ list_add_tail(&new->list, list2);
+ new->index = index;
+
+ } else if (index >= 0) {
+ struct robust_list2_entry *curr;
+
+ if (list_empty(list2))
+ return -ENOENT;
+
+ list_for_each_entry(curr, list2, list) {
+ if (index == curr->index) {
+ new = curr;
+ break;
+ }
+ }
+
+ if (!new)
+ return -ENOENT;
+ }
+
+ BUG_ON(!new);
+ new->head = head;
+ new->list_type = type;
+
+ return index;
+}
+
+struct robust_list_head __user *get_robust_list2(int index, struct task_struct *task)
+{
+ struct list_head *list2 = &task->robust_list2;
+ struct robust_list2_entry *curr;
+
+ if (list_empty(list2) || index == -1)
+ return NULL;
+
+ list_for_each_entry(curr, list2, list) {
+ if (index == curr->index)
+ return curr->head;
+ }
+
+ return NULL;
+}
+
#ifdef CONFIG_FUTEX_PI
/*
@@ -1411,24 +1476,28 @@ static inline void exit_pi_state_list(struct task_struct *curr) { }
static void futex_cleanup(struct task_struct *tsk)
{
-#ifdef CONFIG_64BIT
- if (unlikely(tsk->robust_list)) {
- exit_robust_list64(tsk);
- tsk->robust_list = NULL;
- }
-#else
- if (unlikely(tsk->robust_list)) {
- exit_robust_list32(tsk);
- tsk->robust_list = NULL;
- }
-#endif
+ struct robust_list2_entry *curr, *n;
+ struct list_head *list2 = &tsk->robust_list2;
-#ifdef CONFIG_COMPAT
- if (unlikely(tsk->compat_robust_list)) {
- exit_robust_list32(tsk);
- tsk->compat_robust_list = NULL;
+ /*
+ * Walk through the linked list, parsing robust lists and freeing the
+ * allocated lists
+ */
+ if (unlikely(!list_empty(list2))) {
+ list_for_each_entry_safe(curr, n, list2, list) {
+ if (curr->head != NULL) {
+ if (curr->list_type == ROBUST_LIST_64BIT)
+ exit_robust_list64(tsk, curr->head);
+ else if (curr->list_type == ROBUST_LIST_32BIT)
+ exit_robust_list32(tsk, curr->head);
+ curr->head = NULL;
+ }
+ list_del_init(&curr->list);
+ kfree(curr);
+ }
}
-#endif
+
+ tsk->robust_list_index = -1;
if (unlikely(!list_empty(&tsk->pi_state_list)))
exit_pi_state_list(tsk);
diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h
index fcd1617212eed0e3c2367d2b463a0e019eda6d13..67201e51fa1798a21ff68f60b1e35977b9bd267b 100644
--- a/kernel/futex/futex.h
+++ b/kernel/futex/futex.h
@@ -467,6 +467,11 @@ extern int __futex_wait(u32 __user *uaddr, unsigned int flags, u32 val,
extern int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val,
ktime_t *abs_time, u32 bitset);
+extern long do_set_robust_list2(struct robust_list_head __user *head,
+ int index, unsigned int type);
+
+extern struct robust_list_head __user *get_robust_list2(int index, struct task_struct *task);
+
/**
* struct futex_vector - Auxiliary struct for futex_waitv()
* @w: Userspace provided data
diff --git a/kernel/futex/syscalls.c b/kernel/futex/syscalls.c
index dba193dfd216cc929c8f4d979aa2bcd99237e2d8..56ee1123cbd8ea26c8d22aa74e5faed2974ec577 100644
--- a/kernel/futex/syscalls.c
+++ b/kernel/futex/syscalls.c
@@ -20,6 +20,18 @@
* the list. There can only be one such pending lock.
*/
+#ifdef CONFIG_64BIT
+static inline int robust_list_native_type(void)
+{
+ return ROBUST_LIST_64BIT;
+}
+#else
+static inline int robust_list_native_type(void)
+{
+ return ROBUST_LIST_32BIT;
+}
+#endif
+
/**
* sys_set_robust_list() - Set the robust-futex list head of a task
* @head: pointer to the list-head
@@ -28,17 +40,63 @@
SYSCALL_DEFINE2(set_robust_list, struct robust_list_head __user *, head,
size_t, len)
{
+ unsigned int type = robust_list_native_type();
+ int ret;
+
/*
* The kernel knows only one size for now:
*/
if (unlikely(len != sizeof(*head)))
return -EINVAL;
- current->robust_list = head;
+ ret = do_set_robust_list2(head, current->robust_list_index, type);
+ if (ret < 0)
+ return ret;
+
+ current->robust_list_index = ret;
return 0;
}
+#define ROBUST_LIST_FLAGS ROBUST_LIST_TYPE_MASK
+
+/*
+ * sys_set_robust_list2()
+ *
+ * When index == -1, create a new list for user. When index >= 0, try to find
+ * the corresponding list and re-set the head there.
+ *
+ * Return values:
+ * >= 0: success, index of the robust list
+ * -EINVAL: invalid flags, invalid index
+ * -ENOENT: requested index no where to be found
+ * -ENOMEM: error allocating new list
+ * -ESRCH: too many allocated lists
+ */
+SYSCALL_DEFINE3(set_robust_list2, struct robust_list_head __user *, head,
+ int, index, unsigned int, flags)
+{
+ unsigned int type;
+
+ type = flags & ROBUST_LIST_TYPE_MASK;
+
+ if (index < -1 || index >= ROBUST_LISTS_PER_TASK)
+ return -EINVAL;
+
+ if ((flags & ~ROBUST_LIST_FLAGS) != 0)
+ return -EINVAL;
+
+ if (((uintptr_t) head % sizeof(u32)) != 0)
+ return -EINVAL;
+
+#ifndef CONFIG_64BIT
+ if (type == ROBUST_LIST_64BIT)
+ return -EINVAL;
+#endif
+
+ return do_set_robust_list2(head, index, type);
+}
+
/**
* sys_get_robust_list() - Get the robust-futex list head of a task
* @pid: pid of the process [zero for current task]
@@ -52,6 +110,7 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
struct robust_list_head __user *head;
unsigned long ret;
struct task_struct *p;
+ int index;
rcu_read_lock();
@@ -68,9 +127,11 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
goto err_unlock;
- head = p->robust_list;
+ index = p->robust_list_index;
rcu_read_unlock();
+ head = get_robust_list2(index, p);
+
if (put_user(sizeof(*head), len_ptr))
return -EFAULT;
return put_user(head, head_ptr);
@@ -443,10 +504,19 @@ COMPAT_SYSCALL_DEFINE2(set_robust_list,
struct robust_list_head32 __user *, head,
compat_size_t, len)
{
+ unsigned int type = ROBUST_LIST_32BIT;
+ int ret;
+
if (unlikely(len != sizeof(*head)))
return -EINVAL;
- current->compat_robust_list = head;
+ ret = do_set_robust_list2((struct robust_list_head __user *) head,
+ current->robust_list_index, type);
+ if (ret < 0)
+ return ret;
+
+ current->robust_list_index = ret;
+
return 0;
}
@@ -458,6 +528,7 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid,
struct robust_list_head32 __user *head;
unsigned long ret;
struct task_struct *p;
+ int index;
rcu_read_lock();
@@ -474,9 +545,11 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid,
if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
goto err_unlock;
- head = p->compat_robust_list;
+ index = p->compat_robust_list_index;
rcu_read_unlock();
+ head = (struct robust_list_head32 __user *) get_robust_list2(index, p);
+
if (put_user(sizeof(*head), len_ptr))
return -EFAULT;
return put_user(ptr_to_compat(head), head_ptr);
--
2.49.0
^ permalink raw reply related
* [PATCH v4 5/7] futex: Wire up set_robust_list2 syscall
From: André Almeida @ 2025-05-20 20:48 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Peter Zijlstra, Darren Hart,
Davidlohr Bueso, Shuah Khan, Arnd Bergmann,
Sebastian Andrzej Siewior, Waiman Long
Cc: linux-kernel, linux-kselftest, linux-api, André Almeida
In-Reply-To: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com>
Wire up the new set_robust_list2 syscall in all available architectures.
Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
arch/alpha/kernel/syscalls/syscall.tbl | 1 +
arch/arm/tools/syscall.tbl | 1 +
arch/m68k/kernel/syscalls/syscall.tbl | 1 +
arch/microblaze/kernel/syscalls/syscall.tbl | 1 +
arch/mips/kernel/syscalls/syscall_n32.tbl | 1 +
arch/mips/kernel/syscalls/syscall_n64.tbl | 1 +
arch/mips/kernel/syscalls/syscall_o32.tbl | 1 +
arch/parisc/kernel/syscalls/syscall.tbl | 1 +
arch/powerpc/kernel/syscalls/syscall.tbl | 1 +
arch/s390/kernel/syscalls/syscall.tbl | 1 +
arch/sh/kernel/syscalls/syscall.tbl | 1 +
arch/sparc/kernel/syscalls/syscall.tbl | 1 +
arch/x86/entry/syscalls/syscall_32.tbl | 1 +
arch/x86/entry/syscalls/syscall_64.tbl | 1 +
arch/xtensa/kernel/syscalls/syscall.tbl | 1 +
kernel/sys_ni.c | 1 +
scripts/syscall.tbl | 1 +
17 files changed, 17 insertions(+)
diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index 2dd6340de6b4efddc406f0c235701c15cf02f650..aecc167ac7706d25da73db8099f0813e268b820c 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl
@@ -507,3 +507,4 @@
575 common listxattrat sys_listxattrat
576 common removexattrat sys_removexattrat
577 common open_tree_attr sys_open_tree_attr
+578 common set_robust_list2 sys_robust_list2
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index 27c1d5ebcd91c8c296dc6676307f66bfdf4ab78d..2e47ae5dc9a426d8e5e9dacf29caa54223cf2f5a 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -482,3 +482,4 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index 9fe47112c586f152662af38a9a7f90957cb96cf8..7bcc8cc628c80a44fea2b53d5c69ab5e5f10a1d2 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl
@@ -467,3 +467,4 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index 7b6e97828e552d4da90046ddfcd4a55723e522bb..cd23608afe7e7dadfbf8e21df0486b85bfcb99ce 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
@@ -473,3 +473,4 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index aa70e371bb54ab5d9c8dd8923b6ecf9693ee914d..0a31452ef6ed8fee8f1e2ead5d44acfbbe275fe9 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -406,3 +406,4 @@
465 n32 listxattrat sys_listxattrat
466 n32 removexattrat sys_removexattrat
467 n32 open_tree_attr sys_open_tree_attr
+468 n32 set_robust_list2 sys_set_robust_list2
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index 1e8c44c7b61492eabf00c777831e457a7a6e579c..4cb5a72256338f6fb407f940f1883d523113d609 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -382,3 +382,4 @@
465 n64 listxattrat sys_listxattrat
466 n64 removexattrat sys_removexattrat
467 n64 open_tree_attr sys_open_tree_attr
+468 n64 set_robust_list2 sys_set_robust_list2
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 114a5a1a62302e32dd74d1679ff423a2d57c3c6b..c46238e9edd00d2861edcfa87c5ce7a62bfdc3d4 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -455,3 +455,4 @@
465 o32 listxattrat sys_listxattrat
466 o32 removexattrat sys_removexattrat
467 o32 open_tree_attr sys_open_tree_attr
+468 o32 set_robust_list2 sys_set_robust_list2
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index 94df3cb957e9d547d192e8732c0cf23ef2b5ce5d..71071489a18375013bbfbe26578a634283c1e07b 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -466,3 +466,4 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index 9a084bdb892694bc562f514b55212d167cbac12f..edc4d0bef3f1c7ab826ea8180e7f5ceba4774c07 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -558,3 +558,4 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index a4569b96ef06c54ce7aa795d039541c90a38284f..ff8c594073ec8c3486cc61544d14a338d3f3a906 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -470,3 +470,4 @@
465 common listxattrat sys_listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2 sys_set_robust_list2
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index 52a7652fcff6394b96ace1f3b0ed72250ee5e669..507789194570a9e7b492b210be30bb41021be289 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -471,3 +471,4 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 83e45eb6c095a36baaf749927628e6052fe900e6..8d1122c2235b8d5082a11392e68787efe55f58be 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -513,3 +513,4 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index ac007ea00979dc28b0ef7c002a0615ce86dd3101..cbc0c469e66ecf7b8a61e82c38b07ecc63f6fe23 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -473,3 +473,4 @@
465 i386 listxattrat sys_listxattrat
466 i386 removexattrat sys_removexattrat
467 i386 open_tree_attr sys_open_tree_attr
+468 i386 set_robust_list2 sys_set_robust_list2
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index cfb5ca41e30de1a4e073750096f5b51a2ec137d2..b420217c72fc50ad90f291812972019606c5ff69 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -391,6 +391,7 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
#
# Due to a historical design error, certain syscalls are numbered differently
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index f657a77314f8667fa019a01e10c84ea270024adc..6b852ee8a1621c7dd24f6cd37fd990f5ff8d8527 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
@@ -438,3 +438,4 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index c00a86931f8c6cb30d35a9d56cbcc5994add90e1..71fbac6176c8886f4fa8dd437b0aedd5f14e9f74 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -195,6 +195,7 @@ COND_SYSCALL(move_pages);
COND_SYSCALL(set_mempolicy_home_node);
COND_SYSCALL(cachestat);
COND_SYSCALL(mseal);
+COND_SYSCALL(set_robust_list2);
COND_SYSCALL(perf_event_open);
COND_SYSCALL(accept4);
diff --git a/scripts/syscall.tbl b/scripts/syscall.tbl
index 580b4e246aecd5f07d542943ba68fc4ed5961660..07d7e776d0329659e70a9a55ffff7ac18eb3ff87 100644
--- a/scripts/syscall.tbl
+++ b/scripts/syscall.tbl
@@ -408,3 +408,4 @@
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
+468 common set_robust_list2 sys_set_robust_list2
--
2.49.0
^ permalink raw reply related
* [PATCH v4 6/7] futex: Remove the limit of elements for sys_set_robust_list2 lists
From: André Almeida @ 2025-05-20 20:48 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Peter Zijlstra, Darren Hart,
Davidlohr Bueso, Shuah Khan, Arnd Bergmann,
Sebastian Andrzej Siewior, Waiman Long
Cc: linux-kernel, linux-kselftest, linux-api, André Almeida
In-Reply-To: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com>
Remove the limit of ROBUST_LIST_LIMIT elements that a robust list can
have, for the ones created with the new interface. This is done by
overwritten the list as it's proceeded in a way that we avoid circular
lists.
For the old interface, we keep the limited behavior to avoid changing
the API.
Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
kernel/futex/core.c | 50 ++++++++++++++++++++++++++++++++++++--------------
1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index 49b3bc592948a811f995017027f33ad8f285531f..61f0b48a2bcd8ab926754980ab3454b9ec13a344 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -1152,7 +1152,8 @@ static inline int fetch_robust_entry(struct robust_list __user **entry,
* We silently return on any sign of list-walking problem.
*/
static void exit_robust_list64(struct task_struct *curr,
- struct robust_list_head __user *head)
+ struct robust_list_head __user *head,
+ bool destroyable)
{
struct robust_list __user *entry, *next_entry, *pending;
unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
@@ -1196,13 +1197,17 @@ static void exit_robust_list64(struct task_struct *curr,
}
if (rc)
return;
- entry = next_entry;
- pi = next_pi;
+
/*
* Avoid excessively long or circular lists:
*/
- if (!--limit)
+ if (!destroyable && !--limit)
break;
+ else
+ put_user(&head->list, &entry->next);
+
+ entry = next_entry;
+ pi = next_pi;
cond_resched();
}
@@ -1214,7 +1219,8 @@ static void exit_robust_list64(struct task_struct *curr,
}
#else
static void exit_robust_list64(struct task_struct *curr,
- struct robust_list_head __user *head)
+ struct robust_list_head __user *head,
+ bool destroyable)
{
pr_warn("32bit kernel should not allow ROBUST_LIST_64BIT");
}
@@ -1252,7 +1258,8 @@ fetch_robust_entry32(u32 *uentry, struct robust_list __user **entry,
* We silently return on any sign of list-walking problem.
*/
static void exit_robust_list32(struct task_struct *curr,
- struct robust_list_head32 __user *head)
+ struct robust_list_head32 __user *head,
+ bool destroyable)
{
struct robust_list __user *entry, *next_entry, *pending;
unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
@@ -1301,14 +1308,17 @@ static void exit_robust_list32(struct task_struct *curr,
}
if (rc)
return;
- uentry = next_uentry;
- entry = next_entry;
- pi = next_pi;
/*
* Avoid excessively long or circular lists:
*/
- if (!--limit)
+ if (!destroyable && !--limit)
break;
+ else
+ put_user((struct robust_list __user *) &head->list, &entry->next);
+
+ uentry = next_uentry;
+ entry = next_entry;
+ pi = next_pi;
cond_resched();
}
@@ -1474,26 +1484,38 @@ static void exit_pi_state_list(struct task_struct *curr)
static inline void exit_pi_state_list(struct task_struct *curr) { }
#endif
+/*
+ * futex_cleanup - After the task exists, process the robust lists
+ *
+ * Walk through the linked list, parsing robust lists and freeing the
+ * allocated lists. Lists created with the set_robust_list2 don't have a limit
+ * for sizing and can be destroyed while we walk on it to avoid circular list.
+ */
static void futex_cleanup(struct task_struct *tsk)
{
struct robust_list2_entry *curr, *n;
struct list_head *list2 = &tsk->robust_list2;
+ bool destroyable = true;
+ int i = 0;
/*
- * Walk through the linked list, parsing robust lists and freeing the
- * allocated lists
*/
if (unlikely(!list_empty(list2))) {
list_for_each_entry_safe(curr, n, list2, list) {
+ destroyable = true;
+ if (tsk->robust_list_index == i)
+ destroyable = false;
+
if (curr->head != NULL) {
if (curr->list_type == ROBUST_LIST_64BIT)
- exit_robust_list64(tsk, curr->head);
+ exit_robust_list64(tsk, curr->head, destroyable);
else if (curr->list_type == ROBUST_LIST_32BIT)
- exit_robust_list32(tsk, curr->head);
+ exit_robust_list32(tsk, curr->head, destroyable);
curr->head = NULL;
}
list_del_init(&curr->list);
kfree(curr);
+ i++;
}
}
--
2.49.0
^ permalink raw reply related
* [PATCH v4 7/7] selftests: futex: Expand robust list test for the new interface
From: André Almeida @ 2025-05-20 20:48 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Peter Zijlstra, Darren Hart,
Davidlohr Bueso, Shuah Khan, Arnd Bergmann,
Sebastian Andrzej Siewior, Waiman Long
Cc: linux-kernel, linux-kselftest, linux-api, André Almeida
In-Reply-To: <20250520-tonyk-robust_futex-v4-0-1123093e59de@igalia.com>
Expand the current robust list test for the new set_robust_list2
syscall. Create an option to make it possible to run the same tests
using the new syscall, and also add two new relevant test: test long
lists (bigger than ROBUST_LIST_LIMIT) and for unaligned addresses.
Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
.../selftests/futex/functional/robust_list.c | 160 ++++++++++++++++++++-
1 file changed, 156 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/futex/functional/robust_list.c b/tools/testing/selftests/futex/functional/robust_list.c
index 42690b2440fd29a9b12c46f67f9645ccc93d1147..004ad79ff6171c411fd47e699e3c38889544218e 100644
--- a/tools/testing/selftests/futex/functional/robust_list.c
+++ b/tools/testing/selftests/futex/functional/robust_list.c
@@ -35,16 +35,45 @@
#include <stddef.h>
#include <sys/mman.h>
#include <sys/wait.h>
+#include <stdint.h>
#define STACK_SIZE (1024 * 1024)
#define FUTEX_TIMEOUT 3
+#define SYS_set_robust_list2 468
+
+enum robust_list2_type {
+ ROBUST_LIST_32BIT,
+ ROBUST_LIST_64BIT,
+};
+
static pthread_barrier_t barrier, barrier2;
+bool robust2 = false;
+
int set_robust_list(struct robust_list_head *head, size_t len)
{
- return syscall(SYS_set_robust_list, head, len);
+ int ret, flags;
+
+ if (!robust2) {
+ return syscall(SYS_set_robust_list, head, len);
+ }
+
+ if (sizeof(head) == 8)
+ flags = ROBUST_LIST_64BIT;
+ else
+ flags = ROBUST_LIST_32BIT;
+
+ /*
+ * We act as we have just one list here. We try to use the first slot,
+ * but if it hasn't been alocated yet we allocate it.
+ */
+ ret = syscall(SYS_set_robust_list2, head, 0, flags);
+ if (ret == -1 && errno == ENOENT)
+ ret = syscall(SYS_set_robust_list2, head, -1, flags);
+
+ return ret;
}
int get_robust_list(int pid, struct robust_list_head **head, size_t *len_ptr)
@@ -246,6 +275,11 @@ static void test_set_robust_list_invalid_size(void)
size_t head_size = sizeof(struct robust_list_head);
int ret;
+ if (robust2) {
+ ksft_test_result_skip("This test is only for old robust interface\n");
+ return;
+ }
+
ret = set_robust_list(&head, head_size);
ASSERT_EQ(ret, 0);
@@ -321,6 +355,11 @@ static void test_get_robust_list_child(void)
struct robust_list_head head, *get_head;
size_t len_ptr;
+ if (robust2) {
+ ksft_test_result_skip("Not implemented in the new robust interface\n");
+ return;
+ }
+
ret = pthread_barrier_init(&barrier, NULL, 2);
ret = pthread_barrier_init(&barrier2, NULL, 2);
ASSERT_EQ(ret, 0);
@@ -332,7 +371,7 @@ static void test_get_robust_list_child(void)
ret = get_robust_list(tid, &get_head, &len_ptr);
ASSERT_EQ(ret, 0);
- ASSERT_EQ(&head, get_head);
+ ASSERT_EQ(get_head, &head);
pthread_barrier_wait(&barrier2);
@@ -507,11 +546,119 @@ static void test_circular_list(void)
ksft_test_result_pass("%s\n", __func__);
}
+#define ROBUST_LIST_LIMIT 2048
+#define CHILD_LIST_LIMIT (ROBUST_LIST_LIMIT + 10)
+
+static int child_robust_list_limit(void *arg)
+{
+ struct lock_struct *locks;
+ struct robust_list *list;
+ struct robust_list_head head;
+ int ret, i;
+
+ locks = (struct lock_struct *) arg;
+
+ ret = set_list(&head);
+ if (ret)
+ ksft_test_result_fail("set_list error\n");
+
+ /*
+ * Create a very long list of locks
+ */
+ head.list.next = &locks[0].list;
+
+ list = head.list.next;
+ for (i = 0; i < CHILD_LIST_LIMIT - 1; i++) {
+ list->next = &locks[i+1].list;
+ list = list->next;
+ }
+ list->next = &head.list;
+
+ /*
+ * Grab the lock in the last one, and die without releasing it
+ */
+ mutex_lock(&locks[CHILD_LIST_LIMIT], &head, false);
+ pthread_barrier_wait(&barrier);
+
+ sleep(1);
+
+ return 0;
+}
+
+/*
+ * The old robust list used to have a limit of 2048 items from the kernel side.
+ * After this limit the kernel stops walking the list and ignore the other
+ * futexes, causing deadlocks.
+ *
+ * For the new interface, test if we can wait for a list of more than 2048
+ * elements.
+ */
+static void test_robust_list_limit(void)
+{
+ struct lock_struct locks[CHILD_LIST_LIMIT + 1];
+ _Atomic(unsigned int) *futex = &locks[CHILD_LIST_LIMIT].futex;
+ struct robust_list_head head;
+ int ret;
+
+ if (!robust2) {
+ ksft_test_result_skip("This test is only for new robust interface\n");
+ return;
+ }
+
+ *futex = 0;
+
+ ret = set_list(&head);
+ ASSERT_EQ(ret, 0);
+
+ ret = pthread_barrier_init(&barrier, NULL, 2);
+ ASSERT_EQ(ret, 0);
+
+ create_child(child_robust_list_limit, locks);
+
+ /*
+ * After the child thread creates the very long list of locks, wait on
+ * the last one.
+ */
+ pthread_barrier_wait(&barrier);
+ ret = mutex_lock(&locks[CHILD_LIST_LIMIT], &head, false);
+
+ if (ret != 0)
+ printf("futex wait returned %d\n", errno);
+ ASSERT_EQ(ret, 0);
+
+ ASSERT_TRUE(*futex | FUTEX_OWNER_DIED);
+
+ wait(NULL);
+ pthread_barrier_destroy(&barrier);
+
+ ksft_test_result_pass("%s\n", __func__);
+}
+
+/*
+ * The kernel should refuse an unaligned head pointer
+ */
+static void test_unaligned_address(void)
+{
+ struct robust_list_head head, *h;
+ int ret;
+
+ if (!robust2) {
+ ksft_test_result_skip("This test is only for new robust interface\n");
+ return;
+ }
+
+ h = (struct robust_list_head *) ((uintptr_t) &head + 1);
+ ret = set_list(h);
+ ASSERT_EQ(ret, -1);
+ ASSERT_EQ(errno, EINVAL);
+}
+
void usage(char *prog)
{
printf("Usage: %s\n", prog);
printf(" -c Use color\n");
printf(" -h Display this help message\n");
+ printf(" -n Use robust2 syscall\n");
printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n",
VQUIET, VCRITICAL, VINFO);
}
@@ -520,7 +667,7 @@ int main(int argc, char *argv[])
{
int c;
- while ((c = getopt(argc, argv, "cht:v:")) != -1) {
+ while ((c = getopt(argc, argv, "chnt:v:")) != -1) {
switch (c) {
case 'c':
log_color(1);
@@ -531,6 +678,9 @@ int main(int argc, char *argv[])
case 'v':
log_verbosity(atoi(optarg));
break;
+ case 'n':
+ robust2 = true;
+ break;
default:
usage(basename(argv[0]));
exit(1);
@@ -538,7 +688,7 @@ int main(int argc, char *argv[])
}
ksft_print_header();
- ksft_set_plan(7);
+ ksft_set_plan(8);
test_robustness();
@@ -548,6 +698,8 @@ int main(int argc, char *argv[])
test_set_list_op_pending();
test_robust_list_multiple_elements();
test_circular_list();
+ test_robust_list_limit();
+ test_unaligned_address();
ksft_print_cnts();
return 0;
--
2.49.0
^ permalink raw reply related
* Re: close(2) with EINTR has been changed by POSIX.1-2024
From: Steffen Nurpmeso @ 2025-05-20 23:16 UTC (permalink / raw)
To: Theodore Ts'o
Cc: Jan Kara, Alejandro Colomar, Alexander Viro, Christian Brauner,
linux-fsdevel, linux-api, linux-man, Steffen Nurpmeso
In-Reply-To: <20250520133705.GE38098@mit.edu>
Theodore Ts'o wrote in
<20250520133705.GE38098@mit.edu>:
|On Tue, May 20, 2025 at 01:19:19AM +0200, Steffen Nurpmeso wrote:
|> They could not do otherwise than talking the status quo, i think.
|> They have explicitly added posix_close() which overcomes the
|> problem (for those operating systems which actually act like
|> that). There is a long RATIONALE on this, it starts on page 747 :)
|
|They could have just added posix_close() which provided well-defined
|semantics without demanding that existing implementations make
|non-backwards compatible changes to close(2). Personally, while they
|were adding posix_close(2) they could have also fixed the disaster
|which is the semantics around close(2) [.]
Well it was a lot of trouble, not only in bug 529[1], with
follow-ups like a thread started by Michael Kerrisk, with an
interesting response by Rich Felker of Musl[2].
In [1] Erik Blake of RedHat/libvirt said for example
The Linux kernel currently always frees the file descriptor (no
chance for a retry; the filedes can immediately be reused by
another open()), for both EINTR and EIO. Maybe it is safer to
state that the fd is _always_ closed, even if failure is
reported?
etc, but Geoff Clare then (this also was in 2012, where one
possibly could have hoped that more operating systems survive /
continue with money/manpower backing by serious companies; just
in case that mattered) came via
HP got it right with HP-UX; AIX and Linux do the wrong thing.
and he has quite some reasoning for descriptors like ttys etc,
where close can linger, which resulted in Erik Blake quoting
Let me make it very, very clear - no matter how many times these
guys assert HP-UX insane behaviour correct, no "fixes" to Linux
one are going to be accepted. Consider it vetoed. By me, in
role of Linux VFS maintainer. And I'm _very_ certain that
getting Linus to agree will be a matter of minutes.
[1] https://www.austingroupbugs.net/view.php?id=529
[2] https://www.mail-archive.com/austin-group-l@opengroup.org/msg00579.html
|[.] and how advisory locks get
|released that were held by other file descriptors and add a profound
|apologies over the insane semantics demanded by POSIX[1].
The new standard added the Linux-style F_OFD_* fcntl(2) locks!
They are yet Linux-only, but NetBSD at least has an issue by
a major contributor (bug 59241):
NetBSD seems to lack the following:
3.237 OFD-Owned File Lock
...
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_237
>How-To-Repeat:
standards inspection
>Fix:
Yes, please! (That or write down a reason why we eschew it.)
|[1] "POSIX advisory locks are broken by design."
| https://www.sqlite.org/src/artifact/c230a7a24?ln=994-1081
|
| - Ted
--End of <20250520133705.GE38098@mit.edu>
--steffen
|
|Der Kragenbaer, The moon bear,
|der holt sich munter he cheerfully and one by one
|einen nach dem anderen runter wa.ks himself off
|(By Robert Gernhardt)
^ permalink raw reply
* Re: [PATCH v5 0/7] fs: introduce file_getattr and file_setattr syscalls
From: Andrey Albershteyn @ 2025-05-21 8:48 UTC (permalink / raw)
To: Dave Chinner
Cc: Amir Goldstein, Christian Brauner, Arnd Bergmann,
Richard Henderson, Matt Turner, Russell King, Catalin Marinas,
Will Deacon, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, James E . J . Bottomley, Helge Deller,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy, Naveen N Rao, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S . Miller, Andreas Larsson, Andy Lutomirski,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Chris Zankel, Max Filippov, Alexander Viro,
Jan Kara, Mickaël Salaün, Günther Noack,
Pali Rohár, Paul Moore, James Morris, Serge E. Hallyn,
Stephen Smalley, Ondrej Mosnacek, Tyler Hicks, Miklos Szeredi,
linux-alpha, linux-kernel, linux-arm-kernel, linux-m68k,
linux-mips, linux-parisc, linuxppc-dev, linux-s390, linux-sh,
sparclinux, linux-fsdevel, linux-security-module, linux-api,
Linux-Arch, selinux, ecryptfs, linux-unionfs, linux-xfs,
Andrey Albershteyn
In-Reply-To: <aCsX4LTpAnGfFjHg@dread.disaster.area>
On 2025-05-19 21:37:04, Dave Chinner wrote:
> On Thu, May 15, 2025 at 12:33:31PM +0200, Amir Goldstein wrote:
> > On Thu, May 15, 2025 at 11:02 AM Christian Brauner <brauner@kernel.org> wrote:
> > >
> > > On Tue, May 13, 2025 at 11:53:23AM +0200, Arnd Bergmann wrote:
> > > > On Tue, May 13, 2025, at 11:17, Andrey Albershteyn wrote:
> > > >
> > > > >
> > > > > long syscall(SYS_file_getattr, int dirfd, const char *pathname,
> > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > > > long syscall(SYS_file_setattr, int dirfd, const char *pathname,
> > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > >
> > > > I don't think we can have both the "struct fsxattr" from the uapi
> > > > headers, and a variable size as an additional argument. I would
> > > > still prefer not having the extensible structure at all and just
> > >
> > > We're not going to add new interfaces that are fixed size unless for the
> > > very basic cases. I don't care if we're doing that somewhere else in the
> > > kernel but we're not doing that for vfs apis.
> > >
> > > > use fsxattr, but if you want to make it extensible in this way,
> > > > it should use a different structure (name). Otherwise adding
> > > > fields after fsx_pad[] would break the ioctl interface.
> > >
> > > Would that really be a problem? Just along the syscall simply add
> > > something like:
> > >
> > > diff --git a/fs/ioctl.c b/fs/ioctl.c
> > > index c91fd2b46a77..d3943805c4be 100644
> > > --- a/fs/ioctl.c
> > > +++ b/fs/ioctl.c
> > > @@ -868,12 +868,6 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > case FS_IOC_SETFLAGS:
> > > return ioctl_setflags(filp, argp);
> > >
> > > - case FS_IOC_FSGETXATTR:
> > > - return ioctl_fsgetxattr(filp, argp);
> > > -
> > > - case FS_IOC_FSSETXATTR:
> > > - return ioctl_fssetxattr(filp, argp);
> > > -
> > > case FS_IOC_GETFSUUID:
> > > return ioctl_getfsuuid(filp, argp);
> > >
> > > @@ -886,6 +880,20 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > break;
> > > }
> > >
> > > + switch (_IOC_NR(cmd)) {
> > > + case _IOC_NR(FS_IOC_FSGETXATTR):
> > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FS_IOC_FSGETXATTR)))
> > > + return SOMETHING_SOMETHING;
> > > + /* Only handle original size. */
> > > + return ioctl_fsgetxattr(filp, argp);
> > > +
> > > + case _IOC_NR(FFS_IOC_FSSETXATTR):
> > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FFS_IOC_FSSETXATTR)))
> > > + return SOMETHING_SOMETHING;
> > > + /* Only handle original size. */
> > > + return ioctl_fssetxattr(filp, argp);
> > > + }
> > > +
> >
> > I think what Arnd means is that we will not be able to change struct
> > sfxattr in uapi
> > going forward, because we are not going to deprecate the ioctls and
>
> There's no need to deprecate anything to rev an ioctl API. We have
> had to solve this "changing struct size" problem previously in XFS
> ioctls. See XFS_IOC_FSGEOMETRY and the older XFS_IOC_FSGEOMETRY_V4
> and XFS_IOC_FSGEOMETRY_V1 versions of the API/ABI.
>
> If we need to increase the structure size, we can rename the existing
> ioctl and struct to fix the version in the API, then use the
> original name for the new ioctl and structure definition.
>
> The only thing we have to make sure of is that the old and new
> structures have exactly the same overlapping structure. i.e.
> extension must always be done by appending new varibles, they can't
> be put in the middle of the structure.
>
> This way applications being rebuild will pick up the new definition
> automatically when the system asserts that it is suppored, whilst
> existing binaries will always still be supported by the kernel.
>
> If the application wants/needs to support all possible kernels, then
> if XFS_IOC_FSGEOMETRY is not supported, call XFS_IOC_FSGEOMETRY_V4,
> and if that fails (only on really old irix!) or you only need
> something in that original subset, call XFS_IOC_FSGEOMETRY_V1 which
> will always succeed....
>
> > Should we will need to depart from this struct definition and we might
> > as well do it for the initial release of the syscall rather than later on, e.g.:
> >
> > --- a/include/uapi/linux/fs.h
> > +++ b/include/uapi/linux/fs.h
> > @@ -148,6 +148,17 @@ struct fsxattr {
> > unsigned char fsx_pad[8];
> > };
> >
> > +/*
> > + * Variable size structure for file_[sg]et_attr().
> > + */
> > +struct fsx_fileattr {
> > + __u32 fsx_xflags; /* xflags field value (get/set) */
> > + __u32 fsx_extsize; /* extsize field value (get/set)*/
> > + __u32 fsx_nextents; /* nextents field value (get) */
> > + __u32 fsx_projid; /* project identifier (get/set) */
> > + __u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
> > +};
> > +
> > +#define FSXATTR_SIZE_VER0 20
> > +#define FSXATTR_SIZE_LATEST FSXATTR_SIZE_VER0
>
> If all the structures overlap the same, all that is needed in the
> code is to define the structure size that should be copied in and
> parsed. i.e:
>
> case FSXATTR..._V1:
> return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v1));
> case FSXATTR..._V2:
> return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v2));
> case FSXATTR...:
> return ioctl_fsxattr...(args, sizeof(fsx_fileattr));
>
> -Dave.
> --
> Dave Chinner
> david@fromorbit.com
>
So, looks like there's at least two solutions to this concern.
Considering also that we have a bit of space in fsxattr,
'fsx_pad[8]', I think it's fine to stick with the current fsxattr
for now.
--
- Andrey
^ permalink raw reply
* Re: [PATCH v5 0/7] fs: introduce file_getattr and file_setattr syscalls
From: Pali Rohár @ 2025-05-21 8:57 UTC (permalink / raw)
To: Andrey Albershteyn
Cc: Dave Chinner, Amir Goldstein, Christian Brauner, Arnd Bergmann,
Richard Henderson, Matt Turner, Russell King, Catalin Marinas,
Will Deacon, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, James E . J . Bottomley, Helge Deller,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy, Naveen N Rao, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S . Miller, Andreas Larsson, Andy Lutomirski,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Chris Zankel, Max Filippov, Alexander Viro,
Jan Kara, Mickaël Salaün, Günther Noack,
Paul Moore, James Morris, Serge E. Hallyn, Stephen Smalley,
Ondrej Mosnacek, Tyler Hicks, Miklos Szeredi, linux-alpha,
linux-kernel, linux-arm-kernel, linux-m68k, linux-mips,
linux-parisc, linuxppc-dev, linux-s390, linux-sh, sparclinux,
linux-fsdevel, linux-security-module, linux-api, Linux-Arch,
selinux, ecryptfs, linux-unionfs, linux-xfs, Andrey Albershteyn
In-Reply-To: <sfmrojifgnrpeilqxtixyqrdjj5uvvpbvirxmlju5yce7z72vi@ondnx7qbie4y>
On Wednesday 21 May 2025 10:48:26 Andrey Albershteyn wrote:
> On 2025-05-19 21:37:04, Dave Chinner wrote:
> > On Thu, May 15, 2025 at 12:33:31PM +0200, Amir Goldstein wrote:
> > > On Thu, May 15, 2025 at 11:02 AM Christian Brauner <brauner@kernel.org> wrote:
> > > >
> > > > On Tue, May 13, 2025 at 11:53:23AM +0200, Arnd Bergmann wrote:
> > > > > On Tue, May 13, 2025, at 11:17, Andrey Albershteyn wrote:
> > > > >
> > > > > >
> > > > > > long syscall(SYS_file_getattr, int dirfd, const char *pathname,
> > > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > > > > long syscall(SYS_file_setattr, int dirfd, const char *pathname,
> > > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > > >
> > > > > I don't think we can have both the "struct fsxattr" from the uapi
> > > > > headers, and a variable size as an additional argument. I would
> > > > > still prefer not having the extensible structure at all and just
> > > >
> > > > We're not going to add new interfaces that are fixed size unless for the
> > > > very basic cases. I don't care if we're doing that somewhere else in the
> > > > kernel but we're not doing that for vfs apis.
> > > >
> > > > > use fsxattr, but if you want to make it extensible in this way,
> > > > > it should use a different structure (name). Otherwise adding
> > > > > fields after fsx_pad[] would break the ioctl interface.
> > > >
> > > > Would that really be a problem? Just along the syscall simply add
> > > > something like:
> > > >
> > > > diff --git a/fs/ioctl.c b/fs/ioctl.c
> > > > index c91fd2b46a77..d3943805c4be 100644
> > > > --- a/fs/ioctl.c
> > > > +++ b/fs/ioctl.c
> > > > @@ -868,12 +868,6 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > > case FS_IOC_SETFLAGS:
> > > > return ioctl_setflags(filp, argp);
> > > >
> > > > - case FS_IOC_FSGETXATTR:
> > > > - return ioctl_fsgetxattr(filp, argp);
> > > > -
> > > > - case FS_IOC_FSSETXATTR:
> > > > - return ioctl_fssetxattr(filp, argp);
> > > > -
> > > > case FS_IOC_GETFSUUID:
> > > > return ioctl_getfsuuid(filp, argp);
> > > >
> > > > @@ -886,6 +880,20 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > > break;
> > > > }
> > > >
> > > > + switch (_IOC_NR(cmd)) {
> > > > + case _IOC_NR(FS_IOC_FSGETXATTR):
> > > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FS_IOC_FSGETXATTR)))
> > > > + return SOMETHING_SOMETHING;
> > > > + /* Only handle original size. */
> > > > + return ioctl_fsgetxattr(filp, argp);
> > > > +
> > > > + case _IOC_NR(FFS_IOC_FSSETXATTR):
> > > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FFS_IOC_FSSETXATTR)))
> > > > + return SOMETHING_SOMETHING;
> > > > + /* Only handle original size. */
> > > > + return ioctl_fssetxattr(filp, argp);
> > > > + }
> > > > +
> > >
> > > I think what Arnd means is that we will not be able to change struct
> > > sfxattr in uapi
> > > going forward, because we are not going to deprecate the ioctls and
> >
> > There's no need to deprecate anything to rev an ioctl API. We have
> > had to solve this "changing struct size" problem previously in XFS
> > ioctls. See XFS_IOC_FSGEOMETRY and the older XFS_IOC_FSGEOMETRY_V4
> > and XFS_IOC_FSGEOMETRY_V1 versions of the API/ABI.
> >
> > If we need to increase the structure size, we can rename the existing
> > ioctl and struct to fix the version in the API, then use the
> > original name for the new ioctl and structure definition.
> >
> > The only thing we have to make sure of is that the old and new
> > structures have exactly the same overlapping structure. i.e.
> > extension must always be done by appending new varibles, they can't
> > be put in the middle of the structure.
> >
> > This way applications being rebuild will pick up the new definition
> > automatically when the system asserts that it is suppored, whilst
> > existing binaries will always still be supported by the kernel.
> >
> > If the application wants/needs to support all possible kernels, then
> > if XFS_IOC_FSGEOMETRY is not supported, call XFS_IOC_FSGEOMETRY_V4,
> > and if that fails (only on really old irix!) or you only need
> > something in that original subset, call XFS_IOC_FSGEOMETRY_V1 which
> > will always succeed....
> >
> > > Should we will need to depart from this struct definition and we might
> > > as well do it for the initial release of the syscall rather than later on, e.g.:
> > >
> > > --- a/include/uapi/linux/fs.h
> > > +++ b/include/uapi/linux/fs.h
> > > @@ -148,6 +148,17 @@ struct fsxattr {
> > > unsigned char fsx_pad[8];
> > > };
> > >
> > > +/*
> > > + * Variable size structure for file_[sg]et_attr().
> > > + */
> > > +struct fsx_fileattr {
> > > + __u32 fsx_xflags; /* xflags field value (get/set) */
> > > + __u32 fsx_extsize; /* extsize field value (get/set)*/
> > > + __u32 fsx_nextents; /* nextents field value (get) */
> > > + __u32 fsx_projid; /* project identifier (get/set) */
> > > + __u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
> > > +};
> > > +
> > > +#define FSXATTR_SIZE_VER0 20
> > > +#define FSXATTR_SIZE_LATEST FSXATTR_SIZE_VER0
> >
> > If all the structures overlap the same, all that is needed in the
> > code is to define the structure size that should be copied in and
> > parsed. i.e:
> >
> > case FSXATTR..._V1:
> > return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v1));
> > case FSXATTR..._V2:
> > return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v2));
> > case FSXATTR...:
> > return ioctl_fsxattr...(args, sizeof(fsx_fileattr));
> >
> > -Dave.
> > --
> > Dave Chinner
> > david@fromorbit.com
> >
>
> So, looks like there's at least two solutions to this concern.
> Considering also that we have a bit of space in fsxattr,
> 'fsx_pad[8]', I think it's fine to stick with the current fsxattr
> for now.
>
> --
> - Andrey
>
It is planned to extend this structure for new windows attributes as was
discussed. And seem that the current free space would not be enough for
everything.
^ permalink raw reply
* Re: [PATCH v5 0/7] fs: introduce file_getattr and file_setattr syscalls
From: Arnd Bergmann @ 2025-05-21 9:02 UTC (permalink / raw)
To: Andrey Albershteyn, Dave Chinner
Cc: Amir Goldstein, Christian Brauner, Richard Henderson, Matt Turner,
Russell King, Catalin Marinas, Will Deacon, Geert Uytterhoeven,
Michal Simek, Thomas Bogendoerfer, James E . J . Bottomley,
Helge Deller, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Naveen N Rao, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Yoshinori Sato, Rich Felker,
John Paul Adrian Glaubitz, David S . Miller, Andreas Larsson,
Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Chris Zankel, Max Filippov,
Alexander Viro, Jan Kara, Mickaël Salaün,
Günther Noack, Pali Rohár, Paul Moore, James Morris,
Serge E. Hallyn, Stephen Smalley, Ondrej Mosnacek, Tyler Hicks,
Miklos Szeredi, linux-alpha, linux-kernel, linux-arm-kernel,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, linux-fsdevel, linux-security-module,
linux-api, Linux-Arch, selinux, ecryptfs, linux-unionfs,
linux-xfs, Andrey Albershteyn
In-Reply-To: <sfmrojifgnrpeilqxtixyqrdjj5uvvpbvirxmlju5yce7z72vi@ondnx7qbie4y>
On Wed, May 21, 2025, at 10:48, Andrey Albershteyn wrote:
> On 2025-05-19 21:37:04, Dave Chinner wrote:
>> > +struct fsx_fileattr {
>> > + __u32 fsx_xflags; /* xflags field value (get/set) */
>> > + __u32 fsx_extsize; /* extsize field value (get/set)*/
>> > + __u32 fsx_nextents; /* nextents field value (get) */
>> > + __u32 fsx_projid; /* project identifier (get/set) */
>> > + __u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
>> > +};
>> > +
>> > +#define FSXATTR_SIZE_VER0 20
>> > +#define FSXATTR_SIZE_LATEST FSXATTR_SIZE_VER0
>>
>> If all the structures overlap the same, all that is needed in the
>> code is to define the structure size that should be copied in and
>> parsed. i.e:
>>
>> case FSXATTR..._V1:
>> return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v1));
>> case FSXATTR..._V2:
>> return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v2));
>> case FSXATTR...:
>> return ioctl_fsxattr...(args, sizeof(fsx_fileattr));
I think user space these days, in particular glibc, expects that
you can build using new kernel headers and run on older kernels
but still get behavior that is compatible with old headers, so
redefining FS_IOC_FSGETXATTR would be considered a bug.
I'm fairly sure that in the past it was common to expect userspace
to never be built against newer headers and run on older kernels,
but the expectation seems to have gradually shifted away from that.
> So, looks like there's at least two solutions to this concern.
> Considering also that we have a bit of space in fsxattr,
> 'fsx_pad[8]', I think it's fine to stick with the current fsxattr
> for now.
You still have to document what you expect to happen with the
padding fields for both the ioctl and the syscall, as the
current behavior of ignoring the padding in the ioctl is not
what we expect for a syscall which tends to check unknown
fields for zero. I don't see a good solution here if you
use the same structure.
Arnd
^ permalink raw reply
* Re: [PATCH v5 0/7] fs: introduce file_getattr and file_setattr syscalls
From: Amir Goldstein @ 2025-05-21 9:36 UTC (permalink / raw)
To: Andrey Albershteyn
Cc: Dave Chinner, Christian Brauner, Arnd Bergmann, Richard Henderson,
Matt Turner, Russell King, Catalin Marinas, Will Deacon,
Geert Uytterhoeven, Michal Simek, Thomas Bogendoerfer,
James E . J . Bottomley, Helge Deller, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Yoshinori Sato, Rich Felker,
John Paul Adrian Glaubitz, David S . Miller, Andreas Larsson,
Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Chris Zankel, Max Filippov,
Alexander Viro, Jan Kara, Mickaël Salaün,
Günther Noack, Pali Rohár, Paul Moore, James Morris,
Serge E. Hallyn, Stephen Smalley, Ondrej Mosnacek, Tyler Hicks,
Miklos Szeredi, linux-alpha, linux-kernel, linux-arm-kernel,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, linux-fsdevel, linux-security-module,
linux-api, Linux-Arch, selinux, ecryptfs, linux-unionfs,
linux-xfs, Andrey Albershteyn
In-Reply-To: <sfmrojifgnrpeilqxtixyqrdjj5uvvpbvirxmlju5yce7z72vi@ondnx7qbie4y>
On Wed, May 21, 2025 at 10:48 AM Andrey Albershteyn <aalbersh@redhat.com> wrote:
>
> On 2025-05-19 21:37:04, Dave Chinner wrote:
> > On Thu, May 15, 2025 at 12:33:31PM +0200, Amir Goldstein wrote:
> > > On Thu, May 15, 2025 at 11:02 AM Christian Brauner <brauner@kernel.org> wrote:
> > > >
> > > > On Tue, May 13, 2025 at 11:53:23AM +0200, Arnd Bergmann wrote:
> > > > > On Tue, May 13, 2025, at 11:17, Andrey Albershteyn wrote:
> > > > >
> > > > > >
> > > > > > long syscall(SYS_file_getattr, int dirfd, const char *pathname,
> > > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > > > > long syscall(SYS_file_setattr, int dirfd, const char *pathname,
> > > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > > >
> > > > > I don't think we can have both the "struct fsxattr" from the uapi
> > > > > headers, and a variable size as an additional argument. I would
> > > > > still prefer not having the extensible structure at all and just
> > > >
> > > > We're not going to add new interfaces that are fixed size unless for the
> > > > very basic cases. I don't care if we're doing that somewhere else in the
> > > > kernel but we're not doing that for vfs apis.
> > > >
> > > > > use fsxattr, but if you want to make it extensible in this way,
> > > > > it should use a different structure (name). Otherwise adding
> > > > > fields after fsx_pad[] would break the ioctl interface.
> > > >
> > > > Would that really be a problem? Just along the syscall simply add
> > > > something like:
> > > >
> > > > diff --git a/fs/ioctl.c b/fs/ioctl.c
> > > > index c91fd2b46a77..d3943805c4be 100644
> > > > --- a/fs/ioctl.c
> > > > +++ b/fs/ioctl.c
> > > > @@ -868,12 +868,6 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > > case FS_IOC_SETFLAGS:
> > > > return ioctl_setflags(filp, argp);
> > > >
> > > > - case FS_IOC_FSGETXATTR:
> > > > - return ioctl_fsgetxattr(filp, argp);
> > > > -
> > > > - case FS_IOC_FSSETXATTR:
> > > > - return ioctl_fssetxattr(filp, argp);
> > > > -
> > > > case FS_IOC_GETFSUUID:
> > > > return ioctl_getfsuuid(filp, argp);
> > > >
> > > > @@ -886,6 +880,20 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > > break;
> > > > }
> > > >
> > > > + switch (_IOC_NR(cmd)) {
> > > > + case _IOC_NR(FS_IOC_FSGETXATTR):
> > > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FS_IOC_FSGETXATTR)))
> > > > + return SOMETHING_SOMETHING;
> > > > + /* Only handle original size. */
> > > > + return ioctl_fsgetxattr(filp, argp);
> > > > +
> > > > + case _IOC_NR(FFS_IOC_FSSETXATTR):
> > > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FFS_IOC_FSSETXATTR)))
> > > > + return SOMETHING_SOMETHING;
> > > > + /* Only handle original size. */
> > > > + return ioctl_fssetxattr(filp, argp);
> > > > + }
> > > > +
> > >
> > > I think what Arnd means is that we will not be able to change struct
> > > sfxattr in uapi
> > > going forward, because we are not going to deprecate the ioctls and
> >
> > There's no need to deprecate anything to rev an ioctl API. We have
> > had to solve this "changing struct size" problem previously in XFS
> > ioctls. See XFS_IOC_FSGEOMETRY and the older XFS_IOC_FSGEOMETRY_V4
> > and XFS_IOC_FSGEOMETRY_V1 versions of the API/ABI.
> >
> > If we need to increase the structure size, we can rename the existing
> > ioctl and struct to fix the version in the API, then use the
> > original name for the new ioctl and structure definition.
> >
> > The only thing we have to make sure of is that the old and new
> > structures have exactly the same overlapping structure. i.e.
> > extension must always be done by appending new varibles, they can't
> > be put in the middle of the structure.
> >
> > This way applications being rebuild will pick up the new definition
> > automatically when the system asserts that it is suppored, whilst
> > existing binaries will always still be supported by the kernel.
> >
> > If the application wants/needs to support all possible kernels, then
> > if XFS_IOC_FSGEOMETRY is not supported, call XFS_IOC_FSGEOMETRY_V4,
> > and if that fails (only on really old irix!) or you only need
> > something in that original subset, call XFS_IOC_FSGEOMETRY_V1 which
> > will always succeed....
> >
> > > Should we will need to depart from this struct definition and we might
> > > as well do it for the initial release of the syscall rather than later on, e.g.:
> > >
> > > --- a/include/uapi/linux/fs.h
> > > +++ b/include/uapi/linux/fs.h
> > > @@ -148,6 +148,17 @@ struct fsxattr {
> > > unsigned char fsx_pad[8];
> > > };
> > >
> > > +/*
> > > + * Variable size structure for file_[sg]et_attr().
> > > + */
> > > +struct fsx_fileattr {
> > > + __u32 fsx_xflags; /* xflags field value (get/set) */
> > > + __u32 fsx_extsize; /* extsize field value (get/set)*/
> > > + __u32 fsx_nextents; /* nextents field value (get) */
> > > + __u32 fsx_projid; /* project identifier (get/set) */
> > > + __u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
> > > +};
> > > +
> > > +#define FSXATTR_SIZE_VER0 20
> > > +#define FSXATTR_SIZE_LATEST FSXATTR_SIZE_VER0
> >
> > If all the structures overlap the same, all that is needed in the
> > code is to define the structure size that should be copied in and
> > parsed. i.e:
> >
> > case FSXATTR..._V1:
> > return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v1));
> > case FSXATTR..._V2:
> > return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v2));
> > case FSXATTR...:
> > return ioctl_fsxattr...(args, sizeof(fsx_fileattr));
> >
> > -Dave.
> > --
> > Dave Chinner
> > david@fromorbit.com
> >
>
> So, looks like there's at least two solutions to this concern.
> Considering also that we have a bit of space in fsxattr,
> 'fsx_pad[8]', I think it's fine to stick with the current fsxattr
> for now.
Not sure which two solutions you are referring to.
I proposed fsx_fileattr as what I think is the path of least resistance.
There are opinions that we may be able to avoid defining
this struct, but I don't think there was any objection to adding it.
So unless I am missing an objection that I did not understand
define it and get over this hurdle?
Thanks,
Amir.
^ permalink raw reply
* Re: [PATCH v5 0/7] fs: introduce file_getattr and file_setattr syscalls
From: Andrey Albershteyn @ 2025-05-21 10:06 UTC (permalink / raw)
To: Amir Goldstein, pali
Cc: Dave Chinner, Christian Brauner, Arnd Bergmann, Richard Henderson,
Matt Turner, Russell King, Catalin Marinas, Will Deacon,
Geert Uytterhoeven, Michal Simek, Thomas Bogendoerfer,
James E . J . Bottomley, Helge Deller, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Yoshinori Sato, Rich Felker,
John Paul Adrian Glaubitz, David S . Miller, Andreas Larsson,
Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Chris Zankel, Max Filippov,
Alexander Viro, Jan Kara, Mickaël Salaün,
Günther Noack, Pali Rohár, Paul Moore, James Morris,
Serge E. Hallyn, Stephen Smalley, Ondrej Mosnacek, Tyler Hicks,
Miklos Szeredi, linux-alpha, linux-kernel, linux-arm-kernel,
linux-m68k, linux-mips, linux-parisc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, linux-fsdevel, linux-security-module,
linux-api, Linux-Arch, selinux, ecryptfs, linux-unionfs,
linux-xfs, Andrey Albershteyn
In-Reply-To: <CAOQ4uxiM+BBNODHfxu=v3XN2ezA-0k54qC5R4qdELbZW+W-xkg@mail.gmail.com>
On 2025-05-21 11:36:31, Amir Goldstein wrote:
> On Wed, May 21, 2025 at 10:48 AM Andrey Albershteyn <aalbersh@redhat.com> wrote:
> >
> > On 2025-05-19 21:37:04, Dave Chinner wrote:
> > > On Thu, May 15, 2025 at 12:33:31PM +0200, Amir Goldstein wrote:
> > > > On Thu, May 15, 2025 at 11:02 AM Christian Brauner <brauner@kernel.org> wrote:
> > > > >
> > > > > On Tue, May 13, 2025 at 11:53:23AM +0200, Arnd Bergmann wrote:
> > > > > > On Tue, May 13, 2025, at 11:17, Andrey Albershteyn wrote:
> > > > > >
> > > > > > >
> > > > > > > long syscall(SYS_file_getattr, int dirfd, const char *pathname,
> > > > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > > > > > long syscall(SYS_file_setattr, int dirfd, const char *pathname,
> > > > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > > > >
> > > > > > I don't think we can have both the "struct fsxattr" from the uapi
> > > > > > headers, and a variable size as an additional argument. I would
> > > > > > still prefer not having the extensible structure at all and just
> > > > >
> > > > > We're not going to add new interfaces that are fixed size unless for the
> > > > > very basic cases. I don't care if we're doing that somewhere else in the
> > > > > kernel but we're not doing that for vfs apis.
> > > > >
> > > > > > use fsxattr, but if you want to make it extensible in this way,
> > > > > > it should use a different structure (name). Otherwise adding
> > > > > > fields after fsx_pad[] would break the ioctl interface.
> > > > >
> > > > > Would that really be a problem? Just along the syscall simply add
> > > > > something like:
> > > > >
> > > > > diff --git a/fs/ioctl.c b/fs/ioctl.c
> > > > > index c91fd2b46a77..d3943805c4be 100644
> > > > > --- a/fs/ioctl.c
> > > > > +++ b/fs/ioctl.c
> > > > > @@ -868,12 +868,6 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > > > case FS_IOC_SETFLAGS:
> > > > > return ioctl_setflags(filp, argp);
> > > > >
> > > > > - case FS_IOC_FSGETXATTR:
> > > > > - return ioctl_fsgetxattr(filp, argp);
> > > > > -
> > > > > - case FS_IOC_FSSETXATTR:
> > > > > - return ioctl_fssetxattr(filp, argp);
> > > > > -
> > > > > case FS_IOC_GETFSUUID:
> > > > > return ioctl_getfsuuid(filp, argp);
> > > > >
> > > > > @@ -886,6 +880,20 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > > > break;
> > > > > }
> > > > >
> > > > > + switch (_IOC_NR(cmd)) {
> > > > > + case _IOC_NR(FS_IOC_FSGETXATTR):
> > > > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FS_IOC_FSGETXATTR)))
> > > > > + return SOMETHING_SOMETHING;
> > > > > + /* Only handle original size. */
> > > > > + return ioctl_fsgetxattr(filp, argp);
> > > > > +
> > > > > + case _IOC_NR(FFS_IOC_FSSETXATTR):
> > > > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FFS_IOC_FSSETXATTR)))
> > > > > + return SOMETHING_SOMETHING;
> > > > > + /* Only handle original size. */
> > > > > + return ioctl_fssetxattr(filp, argp);
> > > > > + }
> > > > > +
> > > >
> > > > I think what Arnd means is that we will not be able to change struct
> > > > sfxattr in uapi
> > > > going forward, because we are not going to deprecate the ioctls and
> > >
> > > There's no need to deprecate anything to rev an ioctl API. We have
> > > had to solve this "changing struct size" problem previously in XFS
> > > ioctls. See XFS_IOC_FSGEOMETRY and the older XFS_IOC_FSGEOMETRY_V4
> > > and XFS_IOC_FSGEOMETRY_V1 versions of the API/ABI.
> > >
> > > If we need to increase the structure size, we can rename the existing
> > > ioctl and struct to fix the version in the API, then use the
> > > original name for the new ioctl and structure definition.
> > >
> > > The only thing we have to make sure of is that the old and new
> > > structures have exactly the same overlapping structure. i.e.
> > > extension must always be done by appending new varibles, they can't
> > > be put in the middle of the structure.
> > >
> > > This way applications being rebuild will pick up the new definition
> > > automatically when the system asserts that it is suppored, whilst
> > > existing binaries will always still be supported by the kernel.
> > >
> > > If the application wants/needs to support all possible kernels, then
> > > if XFS_IOC_FSGEOMETRY is not supported, call XFS_IOC_FSGEOMETRY_V4,
> > > and if that fails (only on really old irix!) or you only need
> > > something in that original subset, call XFS_IOC_FSGEOMETRY_V1 which
> > > will always succeed....
> > >
> > > > Should we will need to depart from this struct definition and we might
> > > > as well do it for the initial release of the syscall rather than later on, e.g.:
> > > >
> > > > --- a/include/uapi/linux/fs.h
> > > > +++ b/include/uapi/linux/fs.h
> > > > @@ -148,6 +148,17 @@ struct fsxattr {
> > > > unsigned char fsx_pad[8];
> > > > };
> > > >
> > > > +/*
> > > > + * Variable size structure for file_[sg]et_attr().
> > > > + */
> > > > +struct fsx_fileattr {
> > > > + __u32 fsx_xflags; /* xflags field value (get/set) */
> > > > + __u32 fsx_extsize; /* extsize field value (get/set)*/
> > > > + __u32 fsx_nextents; /* nextents field value (get) */
> > > > + __u32 fsx_projid; /* project identifier (get/set) */
> > > > + __u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
> > > > +};
> > > > +
> > > > +#define FSXATTR_SIZE_VER0 20
> > > > +#define FSXATTR_SIZE_LATEST FSXATTR_SIZE_VER0
> > >
> > > If all the structures overlap the same, all that is needed in the
> > > code is to define the structure size that should be copied in and
> > > parsed. i.e:
> > >
> > > case FSXATTR..._V1:
> > > return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v1));
> > > case FSXATTR..._V2:
> > > return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v2));
> > > case FSXATTR...:
> > > return ioctl_fsxattr...(args, sizeof(fsx_fileattr));
> > >
> > > -Dave.
> > > --
> > > Dave Chinner
> > > david@fromorbit.com
> > >
> >
> > So, looks like there's at least two solutions to this concern.
> > Considering also that we have a bit of space in fsxattr,
> > 'fsx_pad[8]', I think it's fine to stick with the current fsxattr
> > for now.
>
> Not sure which two solutions you are referring to.
Suggested by Christian and Dave
>
> I proposed fsx_fileattr as what I think is the path of least resistance.
> There are opinions that we may be able to avoid defining
> this struct, but I don't think there was any objection to adding it.
>
> So unless I am missing an objection that I did not understand
> define it and get over this hurdle?
I see, sure, I misinterpreted the communication :) no problems, I
will create 'struct fsx_fileattr' then.
Pali, ah sorry, I forgot that you will extend fsxattr right away
--
- Andrey
^ permalink raw reply
* Re: [PATCH v5 0/7] fs: introduce file_getattr and file_setattr syscalls
From: Amir Goldstein @ 2025-05-21 10:44 UTC (permalink / raw)
To: Andrey Albershteyn
Cc: pali, Dave Chinner, Christian Brauner, Arnd Bergmann,
Richard Henderson, Matt Turner, Russell King, Catalin Marinas,
Will Deacon, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, James E . J . Bottomley, Helge Deller,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy, Naveen N Rao, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Rich Felker, John Paul Adrian Glaubitz, David S . Miller,
Andreas Larsson, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Chris Zankel,
Max Filippov, Alexander Viro, Jan Kara, Mickaël Salaün,
Günther Noack, Paul Moore, James Morris, Serge E. Hallyn,
Stephen Smalley, Ondrej Mosnacek, Tyler Hicks, Miklos Szeredi,
linux-alpha, linux-kernel, linux-arm-kernel, linux-m68k,
linux-mips, linux-parisc, linuxppc-dev, linux-s390, linux-sh,
sparclinux, linux-fsdevel, linux-security-module, linux-api,
Linux-Arch, selinux, ecryptfs, linux-unionfs, linux-xfs,
Andrey Albershteyn
In-Reply-To: <mw2d36mqwzqoveguw5vlggrnw2wirsbhdxkox33z3fg7k6huz6@hj4ntgg3oj7p>
On Wed, May 21, 2025 at 12:06 PM Andrey Albershteyn <aalbersh@redhat.com> wrote:
>
> On 2025-05-21 11:36:31, Amir Goldstein wrote:
> > On Wed, May 21, 2025 at 10:48 AM Andrey Albershteyn <aalbersh@redhat.com> wrote:
> > >
> > > On 2025-05-19 21:37:04, Dave Chinner wrote:
> > > > On Thu, May 15, 2025 at 12:33:31PM +0200, Amir Goldstein wrote:
> > > > > On Thu, May 15, 2025 at 11:02 AM Christian Brauner <brauner@kernel.org> wrote:
> > > > > >
> > > > > > On Tue, May 13, 2025 at 11:53:23AM +0200, Arnd Bergmann wrote:
> > > > > > > On Tue, May 13, 2025, at 11:17, Andrey Albershteyn wrote:
> > > > > > >
> > > > > > > >
> > > > > > > > long syscall(SYS_file_getattr, int dirfd, const char *pathname,
> > > > > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > > > > > > long syscall(SYS_file_setattr, int dirfd, const char *pathname,
> > > > > > > > struct fsxattr *fsx, size_t size, unsigned int at_flags);
> > > > > > >
> > > > > > > I don't think we can have both the "struct fsxattr" from the uapi
> > > > > > > headers, and a variable size as an additional argument. I would
> > > > > > > still prefer not having the extensible structure at all and just
> > > > > >
> > > > > > We're not going to add new interfaces that are fixed size unless for the
> > > > > > very basic cases. I don't care if we're doing that somewhere else in the
> > > > > > kernel but we're not doing that for vfs apis.
> > > > > >
> > > > > > > use fsxattr, but if you want to make it extensible in this way,
> > > > > > > it should use a different structure (name). Otherwise adding
> > > > > > > fields after fsx_pad[] would break the ioctl interface.
> > > > > >
> > > > > > Would that really be a problem? Just along the syscall simply add
> > > > > > something like:
> > > > > >
> > > > > > diff --git a/fs/ioctl.c b/fs/ioctl.c
> > > > > > index c91fd2b46a77..d3943805c4be 100644
> > > > > > --- a/fs/ioctl.c
> > > > > > +++ b/fs/ioctl.c
> > > > > > @@ -868,12 +868,6 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > > > > case FS_IOC_SETFLAGS:
> > > > > > return ioctl_setflags(filp, argp);
> > > > > >
> > > > > > - case FS_IOC_FSGETXATTR:
> > > > > > - return ioctl_fsgetxattr(filp, argp);
> > > > > > -
> > > > > > - case FS_IOC_FSSETXATTR:
> > > > > > - return ioctl_fssetxattr(filp, argp);
> > > > > > -
> > > > > > case FS_IOC_GETFSUUID:
> > > > > > return ioctl_getfsuuid(filp, argp);
> > > > > >
> > > > > > @@ -886,6 +880,20 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
> > > > > > break;
> > > > > > }
> > > > > >
> > > > > > + switch (_IOC_NR(cmd)) {
> > > > > > + case _IOC_NR(FS_IOC_FSGETXATTR):
> > > > > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FS_IOC_FSGETXATTR)))
> > > > > > + return SOMETHING_SOMETHING;
> > > > > > + /* Only handle original size. */
> > > > > > + return ioctl_fsgetxattr(filp, argp);
> > > > > > +
> > > > > > + case _IOC_NR(FFS_IOC_FSSETXATTR):
> > > > > > + if (WARN_ON_ONCE(_IOC_TYPE(cmd) != _IOC_TYPE(FFS_IOC_FSSETXATTR)))
> > > > > > + return SOMETHING_SOMETHING;
> > > > > > + /* Only handle original size. */
> > > > > > + return ioctl_fssetxattr(filp, argp);
> > > > > > + }
> > > > > > +
> > > > >
> > > > > I think what Arnd means is that we will not be able to change struct
> > > > > sfxattr in uapi
> > > > > going forward, because we are not going to deprecate the ioctls and
> > > >
> > > > There's no need to deprecate anything to rev an ioctl API. We have
> > > > had to solve this "changing struct size" problem previously in XFS
> > > > ioctls. See XFS_IOC_FSGEOMETRY and the older XFS_IOC_FSGEOMETRY_V4
> > > > and XFS_IOC_FSGEOMETRY_V1 versions of the API/ABI.
> > > >
> > > > If we need to increase the structure size, we can rename the existing
> > > > ioctl and struct to fix the version in the API, then use the
> > > > original name for the new ioctl and structure definition.
> > > >
> > > > The only thing we have to make sure of is that the old and new
> > > > structures have exactly the same overlapping structure. i.e.
> > > > extension must always be done by appending new varibles, they can't
> > > > be put in the middle of the structure.
> > > >
> > > > This way applications being rebuild will pick up the new definition
> > > > automatically when the system asserts that it is suppored, whilst
> > > > existing binaries will always still be supported by the kernel.
> > > >
> > > > If the application wants/needs to support all possible kernels, then
> > > > if XFS_IOC_FSGEOMETRY is not supported, call XFS_IOC_FSGEOMETRY_V4,
> > > > and if that fails (only on really old irix!) or you only need
> > > > something in that original subset, call XFS_IOC_FSGEOMETRY_V1 which
> > > > will always succeed....
> > > >
> > > > > Should we will need to depart from this struct definition and we might
> > > > > as well do it for the initial release of the syscall rather than later on, e.g.:
> > > > >
> > > > > --- a/include/uapi/linux/fs.h
> > > > > +++ b/include/uapi/linux/fs.h
> > > > > @@ -148,6 +148,17 @@ struct fsxattr {
> > > > > unsigned char fsx_pad[8];
> > > > > };
> > > > >
> > > > > +/*
> > > > > + * Variable size structure for file_[sg]et_attr().
> > > > > + */
> > > > > +struct fsx_fileattr {
> > > > > + __u32 fsx_xflags; /* xflags field value (get/set) */
> > > > > + __u32 fsx_extsize; /* extsize field value (get/set)*/
> > > > > + __u32 fsx_nextents; /* nextents field value (get) */
> > > > > + __u32 fsx_projid; /* project identifier (get/set) */
> > > > > + __u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
> > > > > +};
> > > > > +
> > > > > +#define FSXATTR_SIZE_VER0 20
> > > > > +#define FSXATTR_SIZE_LATEST FSXATTR_SIZE_VER0
> > > >
> > > > If all the structures overlap the same, all that is needed in the
> > > > code is to define the structure size that should be copied in and
> > > > parsed. i.e:
> > > >
> > > > case FSXATTR..._V1:
> > > > return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v1));
> > > > case FSXATTR..._V2:
> > > > return ioctl_fsxattr...(args, sizeof(fsx_fileattr_v2));
> > > > case FSXATTR...:
> > > > return ioctl_fsxattr...(args, sizeof(fsx_fileattr));
> > > >
> > > > -Dave.
> > > > --
> > > > Dave Chinner
> > > > david@fromorbit.com
> > > >
> > >
> > > So, looks like there's at least two solutions to this concern.
> > > Considering also that we have a bit of space in fsxattr,
> > > 'fsx_pad[8]', I think it's fine to stick with the current fsxattr
> > > for now.
> >
> > Not sure which two solutions you are referring to.
>
> Suggested by Christian and Dave
>
IIUC, those are suggestions of how we could cope with changing
struct fsxattr in the future, but it is easier not to have to do that.
> >
> > I proposed fsx_fileattr as what I think is the path of least resistance.
> > There are opinions that we may be able to avoid defining
> > this struct, but I don't think there was any objection to adding it.
> >
> > So unless I am missing an objection that I did not understand
> > define it and get over this hurdle?
>
> I see, sure, I misinterpreted the communication :) no problems, I
> will create 'struct fsx_fileattr' then.
>
> Pali, ah sorry, I forgot that you will extend fsxattr right away
>
Much less problems could be caused if fsxattr remain frozen in
time along with the ioctls as we continue to extend the syscalls.
Thanks,
Amir.
P.S. your CC list is a bit much.
I wouldn't trust get_maintainer.pl output when it provides such a huge list
it has some emails that bounce - not nice.
When you are at v5 you should be able to have figured out who is
participating in the review and for the rest, the public lists
linux-fsdevel, linux-api and linux-xfs should be enough.
^ permalink raw reply
* [PATCH net-next v2 1/6] tcp: support writing to a socket in listening state
From: Jeremy Harris @ 2025-05-21 11:45 UTC (permalink / raw)
To: netdev; +Cc: linux-api, edumazet, ncardwell, Jeremy Harris
In-Reply-To: <cover.1747826775.git.jgh@exim.org>
In the tcp sendmsg handler, permit a write in LISTENING state if
a MSG_PRELOAD flag is used. Copy from iovec to a linear sk_buff
for placement on the socket write queue.
Signed-off-by: Jeremy Harris <jgh@exim.org>
---
include/linux/socket.h | 1 +
net/ipv4/tcp.c | 115 ++++++++++++++++++
.../perf/trace/beauty/include/linux/socket.h | 1 +
tools/perf/trace/beauty/msg_flags.c | 3 +
4 files changed, 120 insertions(+)
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 3b262487ec06..b41f4cd4dc97 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -330,6 +330,7 @@ struct ucred {
#define MSG_SOCK_DEVMEM 0x2000000 /* Receive devmem skbs as cmsg */
#define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */
#define MSG_SPLICE_PAGES 0x8000000 /* Splice the pages from the iterator in sendmsg() */
+#define MSG_PRELOAD 0x10000000 /* Preload tx data while listening */
#define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */
#define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exec for file
descriptor received through
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index b7b6ab41b496..9a5daf27c980 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1057,6 +1057,118 @@ int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *copied,
return err;
}
+/* Cut-down version of tcp_sendmsg_locked(), for writing on a listen socket
+ */
+static int tcp_sendmsg_preload(struct sock *sk, struct msghdr *msg)
+{
+ struct sk_buff *skb;
+ struct sockcm_cookie sockc;
+ int flags, err, copied = 0;
+ int size_goal;
+ int process_backlog = 0;
+ long timeo;
+
+ if (sk->sk_state != TCP_LISTEN)
+ return -EINVAL;
+
+ flags = msg->msg_flags;
+
+ sockc = (struct sockcm_cookie){ .tsflags = READ_ONCE(sk->sk_tsflags) };
+
+ timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
+
+ /* Ok commence sending. */
+restart:
+ /* Use a arbitrary "mss" value */
+ size_goal = 1000;
+
+ err = -EPIPE;
+ if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
+ goto do_error;
+
+ while (msg_data_left(msg)) {
+ ssize_t copy = 0;
+
+ skb = tcp_write_queue_tail(sk);
+ if (skb)
+ copy = size_goal - skb->len;
+
+ trace_tcp_sendmsg_locked(sk, msg, skb, size_goal);
+
+ if (copy <= 0 || !tcp_skb_can_collapse_to(skb)) {
+ bool first_skb = !skb;
+
+ /* Limit to only one skb on the sk write queue */
+
+ if (!first_skb)
+ goto out_nopush;
+
+ if (!sk_stream_memory_free(sk))
+ goto wait_for_space;
+
+ if (unlikely(process_backlog >= 16)) {
+ process_backlog = 0;
+ if (sk_flush_backlog(sk))
+ goto restart;
+ }
+
+ skb = tcp_stream_alloc_skb(sk, sk->sk_allocation,
+ first_skb);
+ if (!skb)
+ goto wait_for_space;
+
+ process_backlog++;
+
+#ifdef CONFIG_SKB_DECRYPTED
+ skb->decrypted = !!(flags & MSG_SENDPAGE_DECRYPTED);
+#endif
+ tcp_skb_entail(sk, skb);
+ copy = size_goal;
+ }
+
+ /* Try to append data to the end of skb. */
+ if (copy > msg_data_left(msg))
+ copy = msg_data_left(msg);
+
+ copy = min_t(int, copy, skb_tailroom(skb));
+ err = skb_add_data_nocache(sk, skb, &msg->msg_iter, copy);
+ if (err)
+ goto do_error;
+
+ TCP_SKB_CB(skb)->end_seq += copy;
+ tcp_skb_pcount_set(skb, 0);
+
+ copied += copy;
+ goto out_nopush;
+
+wait_for_space:
+ set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+ tcp_remove_empty_skb(sk);
+
+ err = sk_stream_wait_memory(sk, &timeo);
+ if (err != 0)
+ goto do_error;
+ }
+
+out_nopush:
+ return copied;
+
+do_error:
+ tcp_remove_empty_skb(sk);
+
+ if (copied)
+ goto out_nopush;
+
+ err = sk_stream_error(sk, flags, err);
+ /* make sure we wake any epoll edge trigger waiter */
+ if (unlikely(tcp_rtx_and_write_queues_empty(sk) && err == -EAGAIN)) {
+ sk->sk_write_space(sk);
+ tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED);
+ }
+
+ return err;
+}
+
int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
{
struct net_devmem_dmabuf_binding *binding = NULL;
@@ -1132,6 +1244,9 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
goto out_err;
}
+ if (unlikely(flags & MSG_PRELOAD))
+ return tcp_sendmsg_preload(sk, msg);
+
timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
tcp_rate_check_app_limited(sk); /* is sending application-limited? */
diff --git a/tools/perf/trace/beauty/include/linux/socket.h b/tools/perf/trace/beauty/include/linux/socket.h
index c3322eb3d686..e9ea498169f3 100644
--- a/tools/perf/trace/beauty/include/linux/socket.h
+++ b/tools/perf/trace/beauty/include/linux/socket.h
@@ -330,6 +330,7 @@ struct ucred {
#define MSG_SOCK_DEVMEM 0x2000000 /* Receive devmem skbs as cmsg */
#define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */
#define MSG_SPLICE_PAGES 0x8000000 /* Splice the pages from the iterator in sendmsg() */
+#define MSG_PRELOAD 0x10000000 /* Preload tx data while listening */
#define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */
#define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exec for file
descriptor received through
diff --git a/tools/perf/trace/beauty/msg_flags.c b/tools/perf/trace/beauty/msg_flags.c
index 2da581ff0c80..27e40da9b02d 100644
--- a/tools/perf/trace/beauty/msg_flags.c
+++ b/tools/perf/trace/beauty/msg_flags.c
@@ -20,6 +20,9 @@
#ifndef MSG_SPLICE_PAGES
#define MSG_SPLICE_PAGES 0x8000000
#endif
+#ifndef MSG_PRELOAD
+#define MSG_PRELOAD 0x10000000
+#endif
#ifndef MSG_FASTOPEN
#define MSG_FASTOPEN 0x20000000
#endif
--
2.49.0
^ permalink raw reply related
* [PATCH net-next v2 6/6] tcp: fastopen: extend retransmit-queue trimming to handle linear sk_buff
From: Jeremy Harris @ 2025-05-21 11:45 UTC (permalink / raw)
To: netdev; +Cc: linux-api, edumazet, ncardwell, Jeremy Harris
In-Reply-To: <cover.1747826775.git.jgh@exim.org>
A corner-case for the 3rd-ack after a data-on-synack is for
some but not all of the data to be acked. Support this by
adding to the retransmit-queue trim routine to handle a
linear sk_buff.
Signed-off-by: Jeremy Harris <jgh@exim.org>
---
net/ipv4/tcp_output.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index c50553c1c795..bff5934ff04b 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1708,8 +1708,22 @@ static int __pskb_trim_head(struct sk_buff *skb, int len)
struct skb_shared_info *shinfo;
int i, k, eat;
- DEBUG_NET_WARN_ON_ONCE(skb_headlen(skb));
- eat = len;
+ eat = skb_headlen(skb);
+ if (unlikely(eat)) {
+ if (len < eat)
+ eat = len;
+ skb->head += eat;
+ skb->len -= eat;
+ if (skb->data_len)
+ skb->data_len -= eat;
+
+ eat = len - eat;
+ if (eat == 0)
+ return len;
+ } else {
+ eat = len;
+ }
+
k = 0;
shinfo = skb_shinfo(skb);
for (i = 0; i < shinfo->nr_frags; i++) {
--
2.49.0
^ permalink raw reply related
* [PATCH net-next v2 4/6] tcp: transmit any pending data on receipt of 3rd-ack
From: Jeremy Harris @ 2025-05-21 11:45 UTC (permalink / raw)
To: netdev; +Cc: linux-api, edumazet, ncardwell, Jeremy Harris
In-Reply-To: <cover.1747826775.git.jgh@exim.org>
For the non-fastopen case of prelaod, when the 3rd-ack arrives there
will be data on the write queue. Transmit it immediately
by allowing the SYN_SENT state to run the xmit-recovery code.
Signed-off-by: Jeremy Harris <jgh@exim.org>
---
net/ipv4/tcp_input.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 8ec92dec321a..345a08baaf02 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3900,7 +3900,8 @@ static void tcp_xmit_recovery(struct sock *sk, int rexmit)
{
struct tcp_sock *tp = tcp_sk(sk);
- if (rexmit == REXMIT_NONE || sk->sk_state == TCP_SYN_SENT)
+ if ((rexmit == REXMIT_NONE && sk->sk_state != TCP_SYN_RECV) ||
+ sk->sk_state == TCP_SYN_SENT)
return;
if (unlikely(rexmit == REXMIT_NEW)) {
--
2.49.0
^ permalink raw reply related
* [PATCH net-next v2 3/6] tcp: fastopen: add write-data to fastopen synack packet
From: Jeremy Harris @ 2025-05-21 11:45 UTC (permalink / raw)
To: netdev; +Cc: linux-api, edumazet, ncardwell, Jeremy Harris
In-Reply-To: <cover.1747826775.git.jgh@exim.org>
While building the synack packet, for a fastopen socket
copy data from write queue to the packet.
Move the data from write queue to retransmit queue.
Signed-off-by: Jeremy Harris <jgh@exim.org>
---
net/ipv4/tcp_output.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 3ac8d2d17e1f..c50553c1c795 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3702,7 +3702,7 @@ int tcp_send_synack(struct sock *sk)
/**
* tcp_make_synack - Allocate one skb and build a SYNACK packet.
- * @sk: listener socket
+ * @sk: listener socket (or child socket for fastopen)
* @dst: dst entry attached to the SYNACK. It is consumed and caller
* should not use it again.
* @req: request_sock pointer
@@ -3719,6 +3719,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
struct inet_request_sock *ireq = inet_rsk(req);
const struct tcp_sock *tp = tcp_sk(sk);
struct tcp_out_options opts;
+ struct sock *fastopen_sk = (struct sock *)sk;
struct tcp_key key = {};
struct sk_buff *skb;
int tcp_header_size;
@@ -3748,7 +3749,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
* cpu might call us concurrently.
* sk->sk_wmem_alloc in an atomic, we can promote to rw.
*/
- skb_set_owner_w(skb, (struct sock *)sk);
+ skb_set_owner_w(skb, fastopen_sk);
break;
}
skb_dst_set(skb, dst);
@@ -3831,6 +3832,33 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
th->window = htons(min(req->rsk_rcv_wnd, 65535U));
tcp_options_write(th, NULL, tcp_rsk(req), &opts, &key);
th->doff = (tcp_header_size >> 2);
+
+ /* If this is a FASTOPEN, and there is write-data on the accept socket,
+ * re-copy it to the synack segment. If not FASTOPEN. any data waits
+ * until 3rd-ack arrival.
+ */
+
+ if (synack_type == TCP_SYNACK_FASTOPEN &&
+ !skb_queue_empty(&sk->sk_write_queue)) {
+ struct sk_buff *a_skb = tcp_write_queue_tail(sk);
+ int copy = min_t(int, a_skb->len, skb_tailroom(skb));
+
+ skb_put_data(skb, a_skb->data, copy);
+ TCP_SKB_CB(skb)->end_seq += copy;
+
+ tcp_skb_pcount_set(a_skb, 1);
+ WRITE_ONCE(tcp_sk(fastopen_sk)->write_seq,
+ TCP_SKB_CB(a_skb)->end_seq);
+
+ skb_set_delivery_time(a_skb, now, SKB_CLOCK_MONOTONIC);
+
+ /* Move the data to the retransmit queue.
+ * Code elsewhere implies this is a full child socket and
+ * can be treated as writeable - permitting the cast.
+ */
+ tcp_event_new_data_sent(fastopen_sk, a_skb);
+ }
+
TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
/* Okay, we have all we need - do the md5 hash if needed */
--
2.49.0
^ permalink raw reply related
* [PATCH net-next v2 5/6] tcp: fastopen: retransmit data when only the SYN of a synack-with-data is acked
From: Jeremy Harris @ 2025-05-21 11:45 UTC (permalink / raw)
To: netdev; +Cc: linux-api, edumazet, ncardwell, Jeremy Harris
In-Reply-To: <cover.1747826775.git.jgh@exim.org>
A corner-case for the 3rd-ack after a data-on-synack is for only
the SYN to be acked. Handle this by, in ack processing, when in
SYN_RECV state (the state is not yet updated to ESTABLISHED)
marking the retransmit-queue sk_buff as having been lost.
Signed-off-by: Jeremy Harris <jgh@exim.org>
---
net/ipv4/tcp_input.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 345a08baaf02..a53021edddd5 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4069,6 +4069,18 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
&rexmit);
}
+ /* On receiving a 3rd-ack, if we never sent a packet via
+ * the normal means (which counts them), yet there is data
+ * remaining for retransmit, it was data-on-synack not acked;
+ * mark the skb for retransmission.
+ */
+ if (sk->sk_state == TCP_SYN_RECV && tp->segs_out == 0) {
+ struct sk_buff *skb = tcp_rtx_queue_head(sk);
+
+ if (skb)
+ tcp_mark_skb_lost(sk, skb);
+ }
+
/* If needed, reset TLP/RTO timer when RACK doesn't set. */
if (flag & FLAG_SET_XMIT_TIMER)
tcp_set_xmit_timer(sk);
--
2.49.0
^ permalink raw reply related
* [PATCH net-next v2 0/6] tcp: support preloading data on a listening socket
From: Jeremy Harris @ 2025-05-21 11:44 UTC (permalink / raw)
To: netdev; +Cc: linux-api, edumazet, ncardwell, Jeremy Harris
v2 changes:
- Split out the preload operation to a separate routine from
tcp_sendmsg_locked() and restrict from looping over the supplied
iovec
------
Support write to a listen TCP socket, for immediate
transmission on all later passive connection establishments
parented by the listen socket.
On a normal connection transmission of the data is triggered by the receipt
of the 3rd-ack. On a fastopen (with accepted cookie) connection the data
is sent in the synack packet.
The data preload is done using a sendmsg with a newly-defined flag
(MSG_PRELOAD); the amount of data limited to a single linear sk_buff.
Note that this definition is the last-but-two bit available if "int"
is 32 bits.
Intent: lower latency for server-first protocols using TCP.
Known cases of this use are SMTP and MySQL.
Measurements:
Packet capture (laptop, loopback, TFO requeste) for initial SYN to first
client data packet (5 samples):
- baseline TFO-C 1064 1470 1455 1547 1595 usec
- patched non-TFO 140 150 159 144 153 usec
- patched TFO-C 142 149 149 125 125 usec
Out of scope:
- Client-first protocols
- TLS-on-connect
Testing:
A) packetdrill scripts for
- normal non-TFO
- normal TFO
- synack lost
- 3rd-ack acks only the SYN
- 3rd-ack acks partial data
(NB: packetdrill can only check the data size, not actual content)
B) Application use, running the application testsuite
and manual check of specific cases via packet capture
C) Daily-driver laptop use (not expected to trigger the feature;
only regression-test)
D) KASAN/syzkaller
- enable_syscalls "socket$inet_tcp", "listen", "sendmsg", "accept",
"read", "write", "close", "syz_emit_ethernet", "syz_extract_tcp_res"
- the coverage seems rather limited; the sendmsg onto a listen socket
is there, but I am not convinced actual TCP connections are being
excercised. tcp_minisocks.c is entirely uncovered.
- A need for limiting iteration in the above sendmesg was found (RCU
timeouts), hence v2, but no hint of locking problems.
Eric: could you expand on your previous comment? If it referred to
the listening socket, tcp_sendmsg_locked() is called with the sk
locked.
Jeremy Harris (6):
tcp: support writing to a socket in listening state
tcp: copy write-data from listen socket to accept child socket
tcp: fastopen: add write-data to fastopen synack packet
tcp: transmit any pending data on receipt of 3rd-ack
tcp: fastopen: retransmit data when only the SYN of a synack-with-data
is acked
tcp: fastopen: extend retransmit-queue trimming to handle linear
sk_buff
include/linux/socket.h | 1 +
net/ipv4/tcp.c | 115 ++++++++++++++++++
net/ipv4/tcp_fastopen.c | 3 +-
net/ipv4/tcp_input.c | 15 ++-
net/ipv4/tcp_ipv4.c | 4 +-
net/ipv4/tcp_minisocks.c | 58 ++++++++-
net/ipv4/tcp_output.c | 50 +++++++-
.../perf/trace/beauty/include/linux/socket.h | 1 +
tools/perf/trace/beauty/msg_flags.c | 3 +
9 files changed, 237 insertions(+), 13 deletions(-)
base-commit: f685204c57e87d2a88b159c7525426d70ee745c9
--
2.49.0
^ permalink raw reply
* [PATCH net-next v2 2/6] tcp: copy write-data from listen socket to accept child socket
From: Jeremy Harris @ 2025-05-21 11:45 UTC (permalink / raw)
To: netdev; +Cc: linux-api, edumazet, ncardwell, Jeremy Harris
In-Reply-To: <cover.1747826775.git.jgh@exim.org>
Set the request_sock flag for fastopen earlier, making it available
to the af_ops SYN-handler function.
In that function copy data from the listen socket write queue into an
sk_buff, allocating if needed and adding to the write queue of the
newly-created child socket.
Set sequence number values depending on the fastopen status.
Signed-off-by: Jeremy Harris <jgh@exim.org>
---
net/ipv4/tcp_fastopen.c | 3 ++-
net/ipv4/tcp_ipv4.c | 4 +--
net/ipv4/tcp_minisocks.c | 58 ++++++++++++++++++++++++++++++++++++----
3 files changed, 57 insertions(+), 8 deletions(-)
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 9b83d639b5ac..03a86d0b87ba 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -245,6 +245,8 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
struct sock *child;
bool own_req;
+ tcp_rsk(req)->tfo_listener = true;
+
child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL,
NULL, &own_req);
if (!child)
@@ -261,7 +263,6 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
tp = tcp_sk(child);
rcu_assign_pointer(tp->fastopen_rsk, req);
- tcp_rsk(req)->tfo_listener = true;
/* RFC1323: The window in SYN & SYN/ACK segments is never
* scaled. So correct it appropriately.
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 6a14f9e6fef6..e488effdbdb2 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1747,8 +1747,8 @@ EXPORT_IPV6_MOD(tcp_v4_conn_request);
/*
- * The three way handshake has completed - we got a valid synack -
- * now create the new socket.
+ * The three way handshake has completed - we got a valid synack
+ * (or a FASTOPEN syn) - now create the new socket.
*/
struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 43d7852ce07e..d471531b4a78 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -529,7 +529,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
struct inet_connection_sock *newicsk;
const struct tcp_sock *oldtp;
struct tcp_sock *newtp;
- u32 seq;
+ u32 seq, a_seq, n_seq;
if (!newsk)
return NULL;
@@ -550,9 +550,55 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
newtp->segs_in = 1;
seq = treq->snt_isn + 1;
- newtp->snd_sml = newtp->snd_una = seq;
- WRITE_ONCE(newtp->snd_nxt, seq);
- newtp->snd_up = seq;
+ n_seq = seq;
+ a_seq = seq;
+ newtp->write_seq = seq;
+ newtp->snd_una = seq;
+
+ /* If there is write-data sitting on the listen socket, copy it to
+ * the accept socket. If FASTOPEN we will send it on the synack,
+ * otherwise it sits there until 3rd-ack arrives.
+ */
+
+ if (unlikely(!skb_queue_empty(&sk->sk_write_queue))) {
+ struct sk_buff *l_skb = tcp_send_head(sk),
+ *a_skb = tcp_write_queue_tail(newsk);
+ ssize_t copy = 0;
+
+ if (a_skb)
+ copy = l_skb->len - a_skb->len;
+
+ if (copy <= 0 || !tcp_skb_can_collapse_to(a_skb)) {
+ bool first_skb = tcp_rtx_and_write_queues_empty(newsk);
+
+ a_skb = tcp_stream_alloc_skb(newsk,
+ newsk->sk_allocation,
+ first_skb);
+ if (!a_skb) {
+ /* is this the correct free? */
+ bh_unlock_sock(newsk);
+ sk_free(newsk);
+ return NULL;
+ }
+
+ tcp_skb_entail(newsk, a_skb);
+ }
+ copy = min_t(int, l_skb->len, skb_tailroom(a_skb));
+ skb_put_data(a_skb, l_skb->data, copy);
+
+ TCP_SKB_CB(a_skb)->end_seq += copy;
+
+ a_seq += l_skb->len;
+
+ if (treq->tfo_listener)
+ seq = a_seq;
+
+ /* assumes only one skb on the listen write queue */
+ }
+
+ newtp->snd_sml = seq;
+ WRITE_ONCE(newtp->snd_nxt, a_seq);
+ newtp->snd_up = n_seq;
INIT_LIST_HEAD(&newtp->tsq_node);
INIT_LIST_HEAD(&newtp->tsorted_sent_queue);
@@ -567,7 +613,9 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
newtp->total_retrans = req->num_retrans;
tcp_init_xmit_timers(newsk);
- WRITE_ONCE(newtp->write_seq, newtp->pushed_seq = treq->snt_isn + 1);
+
+ newtp->pushed_seq = n_seq;
+ WRITE_ONCE(newtp->write_seq, a_seq);
if (sock_flag(newsk, SOCK_KEEPOPEN))
tcp_reset_keepalive_timer(newsk, keepalive_time_when(newtp));
--
2.49.0
^ permalink raw reply related
* Re: [PATCH v4 3/7] futex: Use explicit sizes for compat_exit_robust_list
From: kernel test robot @ 2025-05-21 13:32 UTC (permalink / raw)
To: André Almeida, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Darren Hart, Davidlohr Bueso, Shuah Khan, Arnd Bergmann,
Sebastian Andrzej Siewior, Waiman Long
Cc: llvm, oe-kbuild-all, linux-kernel, linux-kselftest, linux-api,
André Almeida
In-Reply-To: <20250520-tonyk-robust_futex-v4-3-1123093e59de@igalia.com>
Hi André,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 3ee84e3dd88e39b55b534e17a7b9a181f1d46809]
url: https://github.com/intel-lab-lkp/linux/commits/Andr-Almeida/selftests-futex-Add-ASSERT_-macros/20250521-045231
base: 3ee84e3dd88e39b55b534e17a7b9a181f1d46809
patch link: https://lore.kernel.org/r/20250520-tonyk-robust_futex-v4-3-1123093e59de%40igalia.com
patch subject: [PATCH v4 3/7] futex: Use explicit sizes for compat_exit_robust_list
config: arm-randconfig-002-20250521 (https://download.01.org/0day-ci/archive/20250521/202505212147.5qoTgcmU-lkp@intel.com/config)
compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project f819f46284f2a79790038e1f6649172789734ae8)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250521/202505212147.5qoTgcmU-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505212147.5qoTgcmU-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from io_uring/notif.c:9:
In file included from io_uring/notif.h:5:
In file included from include/net/sock.h:46:
In file included from include/linux/netdevice.h:44:
In file included from include/uapi/linux/neighbour.h:6:
In file included from include/linux/netlink.h:9:
In file included from include/net/scm.h:13:
In file included from include/net/compat.h:8:
>> include/linux/compat.h:665:35: warning: declaration of 'struct robust_list_head32' will not be visible outside of this function [-Wvisibility]
665 | compat_sys_set_robust_list(struct robust_list_head32 __user *head,
| ^
1 warning generated.
--
In file included from io_uring/uring_cmd.c:9:
In file included from include/net/sock.h:46:
In file included from include/linux/netdevice.h:44:
In file included from include/uapi/linux/neighbour.h:6:
In file included from include/linux/netlink.h:9:
In file included from include/net/scm.h:13:
In file included from include/net/compat.h:8:
>> include/linux/compat.h:665:35: warning: declaration of 'struct robust_list_head32' will not be visible outside of this function [-Wvisibility]
665 | compat_sys_set_robust_list(struct robust_list_head32 __user *head,
| ^
io_uring/uring_cmd.c:311:19: warning: unused function 'io_uring_cmd_getsockopt' [-Wunused-function]
311 | static inline int io_uring_cmd_getsockopt(struct socket *sock,
| ^~~~~~~~~~~~~~~~~~~~~~~
io_uring/uring_cmd.c:338:19: warning: unused function 'io_uring_cmd_setsockopt' [-Wunused-function]
338 | static inline int io_uring_cmd_setsockopt(struct socket *sock,
| ^~~~~~~~~~~~~~~~~~~~~~~
3 warnings generated.
vim +665 include/linux/compat.h
621
622 #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64
623 asmlinkage long compat_sys_pwritev64(unsigned long fd,
624 const struct iovec __user *vec,
625 unsigned long vlen, loff_t pos);
626 #endif
627 asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
628 compat_off_t __user *offset, compat_size_t count);
629 asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
630 compat_loff_t __user *offset, compat_size_t count);
631 asmlinkage long compat_sys_pselect6_time32(int n, compat_ulong_t __user *inp,
632 compat_ulong_t __user *outp,
633 compat_ulong_t __user *exp,
634 struct old_timespec32 __user *tsp,
635 void __user *sig);
636 asmlinkage long compat_sys_pselect6_time64(int n, compat_ulong_t __user *inp,
637 compat_ulong_t __user *outp,
638 compat_ulong_t __user *exp,
639 struct __kernel_timespec __user *tsp,
640 void __user *sig);
641 asmlinkage long compat_sys_ppoll_time32(struct pollfd __user *ufds,
642 unsigned int nfds,
643 struct old_timespec32 __user *tsp,
644 const compat_sigset_t __user *sigmask,
645 compat_size_t sigsetsize);
646 asmlinkage long compat_sys_ppoll_time64(struct pollfd __user *ufds,
647 unsigned int nfds,
648 struct __kernel_timespec __user *tsp,
649 const compat_sigset_t __user *sigmask,
650 compat_size_t sigsetsize);
651 asmlinkage long compat_sys_signalfd4(int ufd,
652 const compat_sigset_t __user *sigmask,
653 compat_size_t sigsetsize, int flags);
654 asmlinkage long compat_sys_newfstatat(unsigned int dfd,
655 const char __user *filename,
656 struct compat_stat __user *statbuf,
657 int flag);
658 asmlinkage long compat_sys_newfstat(unsigned int fd,
659 struct compat_stat __user *statbuf);
660 /* No generic prototype for sync_file_range and sync_file_range2 */
661 asmlinkage long compat_sys_waitid(int, compat_pid_t,
662 struct compat_siginfo __user *, int,
663 struct compat_rusage __user *);
664 asmlinkage long
> 665 compat_sys_set_robust_list(struct robust_list_head32 __user *head,
666 compat_size_t len);
667 asmlinkage long
668 compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
669 compat_size_t __user *len_ptr);
670 asmlinkage long compat_sys_getitimer(int which,
671 struct old_itimerval32 __user *it);
672 asmlinkage long compat_sys_setitimer(int which,
673 struct old_itimerval32 __user *in,
674 struct old_itimerval32 __user *out);
675 asmlinkage long compat_sys_kexec_load(compat_ulong_t entry,
676 compat_ulong_t nr_segments,
677 struct compat_kexec_segment __user *,
678 compat_ulong_t flags);
679 asmlinkage long compat_sys_timer_create(clockid_t which_clock,
680 struct compat_sigevent __user *timer_event_spec,
681 timer_t __user *created_timer_id);
682 asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
683 compat_long_t addr, compat_long_t data);
684 asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
685 unsigned int len,
686 compat_ulong_t __user *user_mask_ptr);
687 asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid,
688 unsigned int len,
689 compat_ulong_t __user *user_mask_ptr);
690 asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
691 compat_stack_t __user *uoss_ptr);
692 asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset,
693 compat_size_t sigsetsize);
694 #ifndef CONFIG_ODD_RT_SIGACTION
695 asmlinkage long compat_sys_rt_sigaction(int,
696 const struct compat_sigaction __user *,
697 struct compat_sigaction __user *,
698 compat_size_t);
699 #endif
700 asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set,
701 compat_sigset_t __user *oset,
702 compat_size_t sigsetsize);
703 asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset,
704 compat_size_t sigsetsize);
705 asmlinkage long compat_sys_rt_sigtimedwait_time32(compat_sigset_t __user *uthese,
706 struct compat_siginfo __user *uinfo,
707 struct old_timespec32 __user *uts, compat_size_t sigsetsize);
708 asmlinkage long compat_sys_rt_sigtimedwait_time64(compat_sigset_t __user *uthese,
709 struct compat_siginfo __user *uinfo,
710 struct __kernel_timespec __user *uts, compat_size_t sigsetsize);
711 asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig,
712 struct compat_siginfo __user *uinfo);
713 /* No generic prototype for rt_sigreturn */
714 asmlinkage long compat_sys_times(struct compat_tms __user *tbuf);
715 asmlinkage long compat_sys_getrlimit(unsigned int resource,
716 struct compat_rlimit __user *rlim);
717 asmlinkage long compat_sys_setrlimit(unsigned int resource,
718 struct compat_rlimit __user *rlim);
719 asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru);
720 asmlinkage long compat_sys_gettimeofday(struct old_timeval32 __user *tv,
721 struct timezone __user *tz);
722 asmlinkage long compat_sys_settimeofday(struct old_timeval32 __user *tv,
723 struct timezone __user *tz);
724 asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
725 asmlinkage long compat_sys_mq_open(const char __user *u_name,
726 int oflag, compat_mode_t mode,
727 struct compat_mq_attr __user *u_attr);
728 asmlinkage long compat_sys_mq_notify(mqd_t mqdes,
729 const struct compat_sigevent __user *u_notification);
730 asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes,
731 const struct compat_mq_attr __user *u_mqstat,
732 struct compat_mq_attr __user *u_omqstat);
733 asmlinkage long compat_sys_msgctl(int first, int second, void __user *uptr);
734 asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp,
735 compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg);
736 asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp,
737 compat_ssize_t msgsz, int msgflg);
738 asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
739 asmlinkage long compat_sys_shmctl(int first, int second, void __user *uptr);
740 asmlinkage long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg);
741 asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, compat_size_t len,
742 unsigned flags, struct sockaddr __user *addr,
743 int __user *addrlen);
744 asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg,
745 unsigned flags);
746 asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg,
747 unsigned int flags);
748 /* No generic prototype for readahead */
749 asmlinkage long compat_sys_keyctl(u32 option,
750 u32 arg2, u32 arg3, u32 arg4, u32 arg5);
751 asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,
752 const compat_uptr_t __user *envp);
753 /* No generic prototype for fadvise64_64 */
754 /* CONFIG_MMU only */
755 asmlinkage long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid,
756 compat_pid_t pid, int sig,
757 struct compat_siginfo __user *uinfo);
758 asmlinkage long compat_sys_recvmmsg_time64(int fd, struct compat_mmsghdr __user *mmsg,
759 unsigned vlen, unsigned int flags,
760 struct __kernel_timespec __user *timeout);
761 asmlinkage long compat_sys_recvmmsg_time32(int fd, struct compat_mmsghdr __user *mmsg,
762 unsigned vlen, unsigned int flags,
763 struct old_timespec32 __user *timeout);
764 asmlinkage long compat_sys_wait4(compat_pid_t pid,
765 compat_uint_t __user *stat_addr, int options,
766 struct compat_rusage __user *ru);
767 asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
768 int, const char __user *);
769 asmlinkage long compat_sys_open_by_handle_at(int mountdirfd,
770 struct file_handle __user *handle,
771 int flags);
772 asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
773 unsigned vlen, unsigned int flags);
774 asmlinkage long compat_sys_execveat(int dfd, const char __user *filename,
775 const compat_uptr_t __user *argv,
776 const compat_uptr_t __user *envp, int flags);
777 asmlinkage ssize_t compat_sys_preadv2(compat_ulong_t fd,
778 const struct iovec __user *vec,
779 compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags);
780 asmlinkage ssize_t compat_sys_pwritev2(compat_ulong_t fd,
781 const struct iovec __user *vec,
782 compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags);
783 #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2
784 asmlinkage long compat_sys_preadv64v2(unsigned long fd,
785 const struct iovec __user *vec,
786 unsigned long vlen, loff_t pos, rwf_t flags);
787 #endif
788
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v4 4/7] futex: Create set_robust_list2
From: kernel test robot @ 2025-05-21 14:24 UTC (permalink / raw)
To: André Almeida, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Darren Hart, Davidlohr Bueso, Shuah Khan, Arnd Bergmann,
Sebastian Andrzej Siewior, Waiman Long
Cc: oe-kbuild-all, linux-kernel, linux-kselftest, linux-api,
André Almeida
In-Reply-To: <20250520-tonyk-robust_futex-v4-4-1123093e59de@igalia.com>
Hi André,
kernel test robot noticed the following build errors:
[auto build test ERROR on 3ee84e3dd88e39b55b534e17a7b9a181f1d46809]
url: https://github.com/intel-lab-lkp/linux/commits/Andr-Almeida/selftests-futex-Add-ASSERT_-macros/20250521-045231
base: 3ee84e3dd88e39b55b534e17a7b9a181f1d46809
patch link: https://lore.kernel.org/r/20250520-tonyk-robust_futex-v4-4-1123093e59de%40igalia.com
patch subject: [PATCH v4 4/7] futex: Create set_robust_list2
config: i386-buildonly-randconfig-003-20250521 (https://download.01.org/0day-ci/archive/20250521/202505212200.ditHHp5E-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250521/202505212200.ditHHp5E-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505212200.ditHHp5E-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from <command-line>:
>> ./usr/include/linux/futex.h:177:26: error: field 'list' has incomplete type
177 | struct list_head list;
| ^~~~
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v4 5/7] futex: Wire up set_robust_list2 syscall
From: kernel test robot @ 2025-05-21 20:23 UTC (permalink / raw)
To: André Almeida, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Darren Hart, Davidlohr Bueso, Shuah Khan, Arnd Bergmann,
Sebastian Andrzej Siewior, Waiman Long
Cc: oe-kbuild-all, linux-kernel, linux-kselftest, linux-api,
André Almeida
In-Reply-To: <20250520-tonyk-robust_futex-v4-5-1123093e59de@igalia.com>
Hi André,
kernel test robot noticed the following build errors:
[auto build test ERROR on 3ee84e3dd88e39b55b534e17a7b9a181f1d46809]
url: https://github.com/intel-lab-lkp/linux/commits/Andr-Almeida/selftests-futex-Add-ASSERT_-macros/20250521-045231
base: 3ee84e3dd88e39b55b534e17a7b9a181f1d46809
patch link: https://lore.kernel.org/r/20250520-tonyk-robust_futex-v4-5-1123093e59de%40igalia.com
patch subject: [PATCH v4 5/7] futex: Wire up set_robust_list2 syscall
config: arc-randconfig-001-20250521 (https://download.01.org/0day-ci/archive/20250522/202505220350.ZektmdF0-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250522/202505220350.ZektmdF0-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505220350.ZektmdF0-lkp@intel.com/
All errors (new ones prefixed by >>):
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:460:1: note: in expansion of macro '__SYSCALL'
460 | __SYSCALL(459, sys_lsm_get_self_attr)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: warning: initialized field overwritten [-Woverride-init]
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:461:1: note: in expansion of macro '__SYSCALL'
461 | __SYSCALL(460, sys_lsm_set_self_attr)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: note: (near initialization for 'sys_call_table[460]')
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:461:1: note: in expansion of macro '__SYSCALL'
461 | __SYSCALL(460, sys_lsm_set_self_attr)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: warning: initialized field overwritten [-Woverride-init]
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:462:1: note: in expansion of macro '__SYSCALL'
462 | __SYSCALL(461, sys_lsm_list_modules)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: note: (near initialization for 'sys_call_table[461]')
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:462:1: note: in expansion of macro '__SYSCALL'
462 | __SYSCALL(461, sys_lsm_list_modules)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: warning: initialized field overwritten [-Woverride-init]
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:463:1: note: in expansion of macro '__SYSCALL'
463 | __SYSCALL(462, sys_mseal)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: note: (near initialization for 'sys_call_table[462]')
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:463:1: note: in expansion of macro '__SYSCALL'
463 | __SYSCALL(462, sys_mseal)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: warning: initialized field overwritten [-Woverride-init]
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:464:1: note: in expansion of macro '__SYSCALL'
464 | __SYSCALL(463, sys_setxattrat)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: note: (near initialization for 'sys_call_table[463]')
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:464:1: note: in expansion of macro '__SYSCALL'
464 | __SYSCALL(463, sys_setxattrat)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: warning: initialized field overwritten [-Woverride-init]
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:465:1: note: in expansion of macro '__SYSCALL'
465 | __SYSCALL(464, sys_getxattrat)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: note: (near initialization for 'sys_call_table[464]')
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:465:1: note: in expansion of macro '__SYSCALL'
465 | __SYSCALL(464, sys_getxattrat)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: warning: initialized field overwritten [-Woverride-init]
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:466:1: note: in expansion of macro '__SYSCALL'
466 | __SYSCALL(465, sys_listxattrat)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: note: (near initialization for 'sys_call_table[465]')
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:466:1: note: in expansion of macro '__SYSCALL'
466 | __SYSCALL(465, sys_listxattrat)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: warning: initialized field overwritten [-Woverride-init]
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:467:1: note: in expansion of macro '__SYSCALL'
467 | __SYSCALL(466, sys_removexattrat)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: note: (near initialization for 'sys_call_table[466]')
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:467:1: note: in expansion of macro '__SYSCALL'
467 | __SYSCALL(466, sys_removexattrat)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: warning: initialized field overwritten [-Woverride-init]
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:468:1: note: in expansion of macro '__SYSCALL'
468 | __SYSCALL(467, sys_open_tree_attr)
| ^~~~~~~~~
arch/arc/kernel/sys.c:13:36: note: (near initialization for 'sys_call_table[467]')
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^
./arch/arc/include/generated/asm/syscall_table_32.h:468:1: note: in expansion of macro '__SYSCALL'
468 | __SYSCALL(467, sys_open_tree_attr)
| ^~~~~~~~~
>> ./arch/arc/include/generated/asm/syscall_table_32.h:469:16: error: 'sys_set_robust_list2' undeclared here (not in a function); did you mean 'sys_set_robust_list'?
469 | __SYSCALL(468, sys_set_robust_list2)
| ^~~~~~~~~~~~~~~~~~~~
arch/arc/kernel/sys.c:13:37: note: in definition of macro '__SYSCALL'
13 | #define __SYSCALL(nr, call) [nr] = (call),
| ^~~~
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH net-next v2 1/6] tcp: support writing to a socket in listening state
From: kernel test robot @ 2025-05-22 7:36 UTC (permalink / raw)
To: Jeremy Harris, netdev
Cc: llvm, oe-kbuild-all, linux-api, edumazet, ncardwell,
Jeremy Harris
In-Reply-To: <d3f47c9b5b08237b6e76f7b0739d59089683c86e.1747826775.git.jgh@exim.org>
Hi Jeremy,
kernel test robot noticed the following build warnings:
[auto build test WARNING on f685204c57e87d2a88b159c7525426d70ee745c9]
url: https://github.com/intel-lab-lkp/linux/commits/Jeremy-Harris/tcp-support-writing-to-a-socket-in-listening-state/20250521-195234
base: f685204c57e87d2a88b159c7525426d70ee745c9
patch link: https://lore.kernel.org/r/d3f47c9b5b08237b6e76f7b0739d59089683c86e.1747826775.git.jgh%40exim.org
patch subject: [PATCH net-next v2 1/6] tcp: support writing to a socket in listening state
config: i386-buildonly-randconfig-001-20250522 (https://download.01.org/0day-ci/archive/20250522/202505221529.hEVx1YPV-lkp@intel.com/config)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250522/202505221529.hEVx1YPV-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505221529.hEVx1YPV-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> net/ipv4/tcp.c:1065:23: warning: variable 'sockc' set but not used [-Wunused-but-set-variable]
1065 | struct sockcm_cookie sockc;
| ^
1 warning generated.
vim +/sockc +1065 net/ipv4/tcp.c
1059
1060 /* Cut-down version of tcp_sendmsg_locked(), for writing on a listen socket
1061 */
1062 static int tcp_sendmsg_preload(struct sock *sk, struct msghdr *msg)
1063 {
1064 struct sk_buff *skb;
> 1065 struct sockcm_cookie sockc;
1066 int flags, err, copied = 0;
1067 int size_goal;
1068 int process_backlog = 0;
1069 long timeo;
1070
1071 if (sk->sk_state != TCP_LISTEN)
1072 return -EINVAL;
1073
1074 flags = msg->msg_flags;
1075
1076 sockc = (struct sockcm_cookie){ .tsflags = READ_ONCE(sk->sk_tsflags) };
1077
1078 timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
1079
1080 /* Ok commence sending. */
1081 restart:
1082 /* Use a arbitrary "mss" value */
1083 size_goal = 1000;
1084
1085 err = -EPIPE;
1086 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
1087 goto do_error;
1088
1089 while (msg_data_left(msg)) {
1090 ssize_t copy = 0;
1091
1092 skb = tcp_write_queue_tail(sk);
1093 if (skb)
1094 copy = size_goal - skb->len;
1095
1096 trace_tcp_sendmsg_locked(sk, msg, skb, size_goal);
1097
1098 if (copy <= 0 || !tcp_skb_can_collapse_to(skb)) {
1099 bool first_skb = !skb;
1100
1101 /* Limit to only one skb on the sk write queue */
1102
1103 if (!first_skb)
1104 goto out_nopush;
1105
1106 if (!sk_stream_memory_free(sk))
1107 goto wait_for_space;
1108
1109 if (unlikely(process_backlog >= 16)) {
1110 process_backlog = 0;
1111 if (sk_flush_backlog(sk))
1112 goto restart;
1113 }
1114
1115 skb = tcp_stream_alloc_skb(sk, sk->sk_allocation,
1116 first_skb);
1117 if (!skb)
1118 goto wait_for_space;
1119
1120 process_backlog++;
1121
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v4 4/7] futex: Create set_robust_list2
From: kernel test robot @ 2025-05-22 11:39 UTC (permalink / raw)
To: André Almeida, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Darren Hart, Davidlohr Bueso, Shuah Khan, Arnd Bergmann,
Sebastian Andrzej Siewior, Waiman Long
Cc: oe-kbuild-all, linux-kernel, linux-kselftest, linux-api,
André Almeida
In-Reply-To: <20250520-tonyk-robust_futex-v4-4-1123093e59de@igalia.com>
Hi André,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 3ee84e3dd88e39b55b534e17a7b9a181f1d46809]
url: https://github.com/intel-lab-lkp/linux/commits/Andr-Almeida/selftests-futex-Add-ASSERT_-macros/20250521-045231
base: 3ee84e3dd88e39b55b534e17a7b9a181f1d46809
patch link: https://lore.kernel.org/r/20250520-tonyk-robust_futex-v4-4-1123093e59de%40igalia.com
patch subject: [PATCH v4 4/7] futex: Create set_robust_list2
config: arm-randconfig-r122-20250522 (https://download.01.org/0day-ci/archive/20250522/202505221953.JKgFsA3U-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce: (https://download.01.org/0day-ci/archive/20250522/202505221953.JKgFsA3U-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505221953.JKgFsA3U-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
kernel/futex/core.c:581:38: sparse: sparse: cast removes address space '__user' of expression
kernel/futex/core.c:581:51: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned int [noderef] [usertype] __user *naddr @@ got void * @@
kernel/futex/core.c:581:51: sparse: expected unsigned int [noderef] [usertype] __user *naddr
kernel/futex/core.c:581:51: sparse: got void *
kernel/futex/core.c:597:38: sparse: sparse: cast removes address space '__user' of expression
kernel/futex/core.c:597:51: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned int [noderef] [usertype] __user *naddr @@ got void * @@
kernel/futex/core.c:597:51: sparse: expected unsigned int [noderef] [usertype] __user *naddr
kernel/futex/core.c:597:51: sparse: got void *
kernel/futex/core.c:1268:59: sparse: sparse: cast removes address space '__user' of expression
>> kernel/futex/core.c:1268:59: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected unsigned int [noderef] [usertype] __user *head @@ got unsigned int [usertype] * @@
kernel/futex/core.c:1268:59: sparse: expected unsigned int [noderef] [usertype] __user *head
kernel/futex/core.c:1268:59: sparse: got unsigned int [usertype] *
kernel/futex/core.c:978:9: sparse: sparse: context imbalance in 'futex_q_lockptr_lock' - wrong count at exit
vim +1268 kernel/futex/core.c
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1247
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1248 /*
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1249 * Walk curr->robust_list (very carefully, it's a userspace list!)
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1250 * and mark any locks found there dead, and notify any waiters.
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1251 *
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1252 * We silently return on any sign of list-walking problem.
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1253 */
1c5e99b662506e kernel/futex/core.c André Almeida 2025-05-20 1254 static void exit_robust_list32(struct task_struct *curr,
1c5e99b662506e kernel/futex/core.c André Almeida 2025-05-20 1255 struct robust_list_head32 __user *head)
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1256 {
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1257 struct robust_list __user *entry, *next_entry, *pending;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1258 unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
3f649ab728cda8 kernel/futex.c Kees Cook 2020-06-03 1259 unsigned int next_pi;
b9412773325c3a kernel/futex/core.c André Almeida 2025-05-20 1260 u32 uentry, next_uentry, upending;
b9412773325c3a kernel/futex/core.c André Almeida 2025-05-20 1261 s32 futex_offset;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1262 int rc;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1263
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1264 /*
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1265 * Fetch the list head (which was registered earlier, via
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1266 * sys_set_robust_list()):
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1267 */
b9412773325c3a kernel/futex/core.c André Almeida 2025-05-20 @1268 if (fetch_robust_entry32((u32 *)&uentry, &entry, (u32 *)&head->list.next, &pi))
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1269 return;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1270 /*
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1271 * Fetch the relative futex offset:
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1272 */
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1273 if (get_user(futex_offset, &head->futex_offset))
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1274 return;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1275 /*
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1276 * Fetch any possibly pending lock-add first, and handle it
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1277 * if it exists:
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1278 */
b9412773325c3a kernel/futex/core.c André Almeida 2025-05-20 1279 if (fetch_robust_entry32(&upending, &pending,
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1280 &head->list_op_pending, &pip))
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1281 return;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1282
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1283 next_entry = NULL; /* avoid warning with gcc */
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1284 while (entry != (struct robust_list __user *) &head->list) {
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1285 /*
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1286 * Fetch the next entry in the list before calling
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1287 * handle_futex_death:
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1288 */
b9412773325c3a kernel/futex/core.c André Almeida 2025-05-20 1289 rc = fetch_robust_entry32(&next_uentry, &next_entry,
b9412773325c3a kernel/futex/core.c André Almeida 2025-05-20 1290 (u32 __user *)&entry->next, &next_pi);
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1291 /*
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1292 * A pending lock might already be on the list, so
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1293 * dont process it twice:
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1294 */
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1295 if (entry != pending) {
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1296 void __user *uaddr = futex_uaddr(entry, futex_offset);
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1297
ca16d5bee59807 kernel/futex.c Yang Tao 2019-11-06 1298 if (handle_futex_death(uaddr, curr, pi,
ca16d5bee59807 kernel/futex.c Yang Tao 2019-11-06 1299 HANDLE_DEATH_LIST))
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1300 return;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1301 }
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1302 if (rc)
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1303 return;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1304 uentry = next_uentry;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1305 entry = next_entry;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1306 pi = next_pi;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1307 /*
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1308 * Avoid excessively long or circular lists:
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1309 */
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1310 if (!--limit)
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1311 break;
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1312
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1313 cond_resched();
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1314 }
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1315 if (pending) {
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1316 void __user *uaddr = futex_uaddr(pending, futex_offset);
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1317
ca16d5bee59807 kernel/futex.c Yang Tao 2019-11-06 1318 handle_futex_death(uaddr, curr, pip, HANDLE_DEATH_PENDING);
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1319 }
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1320 }
04e7712f446058 kernel/futex.c Arnd Bergmann 2018-04-17 1321
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v3 0/7] prctl: introduce PR_SET/GET_THP_POLICY
From: Mike Rapoport @ 2025-05-22 12:10 UTC (permalink / raw)
To: Usama Arif
Cc: Andrew Morton, david, linux-mm, hannes, shakeel.butt, riel, ziy,
laoar.shao, baolin.wang, lorenzo.stoakes, Liam.Howlett, npache,
ryan.roberts, vbabka, jannh, Arnd Bergmann, linux-kernel,
linux-doc, kernel-team, linux-api
In-Reply-To: <20250519223307.3601786-1-usamaarif642@gmail.com>
(cc'ing linux-api)
On Mon, May 19, 2025 at 11:29:52PM +0100, Usama Arif wrote:
> This series allows to change the THP policy of a process, according to the
> value set in arg2, all of which will be inherited during fork+exec:
> - PR_DEFAULT_MADV_HUGEPAGE: This will set VM_HUGEPAGE and clear VM_NOHUGEPAGE
> for the default VMA flags. It will also iterate through every VMA in the
> process and call hugepage_madvise on it, with MADV_HUGEPAGE policy.
> This effectively allows setting MADV_HUGEPAGE on the entire process.
> In an environment where different types of workloads are run on the
> same machine, this will allow workloads that benefit from always having
> hugepages to do so, without regressing those that don't.
> - PR_DEFAULT_MADV_NOHUGEPAGE: This will set VM_NOHUGEPAGE and clear VM_HUGEPAGE
> for the default VMA flags. It will also iterate through every VMA in the
> process and call hugepage_madvise on it, with MADV_NOHUGEPAGE policy.
> This effectively allows setting MADV_NOHUGEPAGE on the entire process.
> In an environment where different types of workloads are run on the
> same machine,this will allow workloads that benefit from having
> hugepages on an madvise basis only to do so, without regressing those
> that benefit from having hugepages always.
> - PR_THP_POLICY_SYSTEM: This will reset (clear) both VM_HUGEPAGE and
> VM_NOHUGEPAGE process for the default flags.
>
> In hyperscalers, we have a single THP policy for the entire fleet.
> We have different types of workloads (e.g. AI/compute/databases/etc)
> running on a single server.
> Some of these workloads will benefit from always getting THP at fault
> (or collapsed by khugepaged), some of them will benefit by only getting
> them at madvise.
>
> This series is useful for 2 usecases:
> 1) global system policy = madvise, while we want some workloads to get THPs
> at fault and by khugepaged :- some processes (e.g. AI workloads) benefits
> from getting THPs at fault (and collapsed by khugepaged). Other workloads
> like databases will incur regression (either a performance regression or
> they are completely memory bound and even a very slight increase in memory
> will cause them to OOM). So what these patches will do is allow setting
> prctl(PR_DEFAULT_MADV_HUGEPAGE) on the AI workloads, (This is how
> workloads are deployed in our (Meta's/Facebook) fleet at this moment).
>
> 2) global system policy = always, while we want some workloads to get THPs
> only on madvise basis :- Same reason as 1). What these patches
> will do is allow setting prctl(PR_DEFAULT_MADV_NOHUGEPAGE) on the database
> workloads. (We hope this is us (Meta) in the near future, if a majority of
> workloads show that they benefit from always, we flip the default host
> setting to "always" across the fleet and workloads that regress can opt-out
> and be "madvise". New services developed will then be tested with always by
> default. "always" is also the default defconfig option upstream, so I would
> imagine this is faced by others as well.)
>
> v2->v3: (Thanks Lorenzo for all the below feedback!)
> v2: https://lore.kernel.org/all/20250515133519.2779639-1-usamaarif642@gmail.com/
> - no more flags2.
> - no more MMF2_...
> - renamed policy to PR_DEFAULT_MADV_(NO)HUGEPAGE
> - mmap_write_lock_killable acquired in PR_GET_THP_POLICY
> - mmap_write lock fixed in PR_SET_THP_POLICY
> - mmap assert check in process_default_madv_hugepage
> - check if hugepage_global_enabled is enabled in the call and account for s390
> - set mm->def_flags VM_HUGEPAGE and VM_NOHUGEPAGE according to the policy in
> the way done by madvise(). I believe VM merge will not be broken in
> this way.
> - process_default_madv_hugepage function that does for_each_vma and calls
> hugepage_madvise.
>
> v1->v2:
> - change from modifying the THP decision making for the process, to modifying
> VMA flags only. This prevents further complicating the logic used to
> determine THP order (Thanks David!)
> - change from using a prctl per policy change to just using PR_SET_THP_POLICY
> and arg2 to set the policy. (Zi Yan)
> - Introduce PR_THP_POLICY_DEFAULT_NOHUGE and PR_THP_POLICY_DEFAULT_SYSTEM
> - Add selftests and documentation.
>
> Usama Arif (7):
> mm: khugepaged: extract vm flag setting outside of hugepage_madvise
> prctl: introduce PR_DEFAULT_MADV_HUGEPAGE for the process
> prctl: introduce PR_DEFAULT_MADV_NOHUGEPAGE for the process
> prctl: introduce PR_THP_POLICY_SYSTEM for the process
> selftests: prctl: introduce tests for PR_DEFAULT_MADV_NOHUGEPAGE
> selftests: prctl: introduce tests for PR_THP_POLICY_DEFAULT_HUGE
> docs: transhuge: document process level THP controls
>
> Documentation/admin-guide/mm/transhuge.rst | 42 +++
> include/linux/huge_mm.h | 2 +
> include/linux/mm.h | 2 +-
> include/linux/mm_types.h | 4 +-
> include/uapi/linux/prctl.h | 6 +
> kernel/sys.c | 53 ++++
> mm/huge_memory.c | 13 +
> mm/khugepaged.c | 26 +-
> tools/include/uapi/linux/prctl.h | 6 +
> .../trace/beauty/include/uapi/linux/prctl.h | 6 +
> tools/testing/selftests/prctl/Makefile | 2 +-
> tools/testing/selftests/prctl/thp_policy.c | 286 ++++++++++++++++++
> 12 files changed, 436 insertions(+), 12 deletions(-)
> create mode 100644 tools/testing/selftests/prctl/thp_policy.c
>
> --
> 2.47.1
>
>
--
Sincerely yours,
Mike.
^ permalink raw reply
* Re: [RFC PATCH 0/5] add process_madvise() flags to modify behaviour
From: Mike Rapoport @ 2025-05-22 12:12 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, Liam R . Howlett, David Hildenbrand,
Vlastimil Babka, Jann Horn, Arnd Bergmann, Christian Brauner,
linux-mm, linux-arch, linux-kernel, SeongJae Park, Usama Arif,
linux-api
In-Reply-To: <cover.1747686021.git.lorenzo.stoakes@oracle.com>
(cc'ing linux-api)
On Mon, May 19, 2025 at 09:52:37PM +0100, Lorenzo Stoakes wrote:
> REVIEWERS NOTES:
> ================
>
> This is a VERY EARLY version of the idea, it's relatively untested, and I'm
> 'putting it out there' for feedback. Any serious version of this will add a
> bunch of self-tests to assert correct behaviour and I will more carefully
> confirm everything's working.
>
> This is based on discussion arising from Usama's series [0], SJ's input on
> the thread around process_madvise() behaviour [1] (and a subsequent
> response by me [2]) and prior discussion about a new madvise() interface
> [3].
>
> [0]: https://lore.kernel.org/linux-mm/20250515133519.2779639-1-usamaarif642@gmail.com/
> [1]: https://lore.kernel.org/linux-mm/20250517162048.36347-1-sj@kernel.org/
> [2]: https://lore.kernel.org/linux-mm/e3ba284c-3cb1-42c1-a0ba-9c59374d0541@lucifer.local/
> [3]: https://lore.kernel.org/linux-mm/c390dd7e-0770-4d29-bb0e-f410ff6678e3@lucifer.local/
>
> ================
>
> Currently, we are rather restricted in how madvise() operations
> proceed. While effort has been put in to expanding what process_madvise()
> can do (that is - unrestricted application of advice to the local process
> alongside recent improvements on the efficiency of TLB operations over
> these batvches), we are still constrained by existing madvise() limitations
> and default behaviours.
>
> This series makes use of the currently unused flags field in
> process_madvise() to provide more flexiblity.
>
> It introduces four flags:
>
> 1. PMADV_SKIP_ERRORS
>
> Currently, when an error arises applying advice in any individual VMA
> (keeping in mind that a range specified to madvise() or as part of the
> iovec passed to process_madvise()), the operation stops where it is and
> returns an error.
>
> This might not be the desired behaviour of the user, who may wish instead
> for the operation to be 'best effort'. By setting this flag, that behaviour
> is obtained.
>
> Since process_madvise() would trivially, if skipping errors, simply return
> the input vector size, we instead return the number of entries in the
> vector which completed successfully without error.
>
> The PMADV_SKIP_ERRORS flag implicitly implies PMADV_NO_ERROR_ON_UNMAPPED.
>
> 2. PMADV_NO_ERROR_ON_UNMAPPED
>
> Currently madvise() has the peculiar behaviour of, if the range specified
> to it contains unmapped range(s), completing the full operation, but
> ultimately returning -ENOMEM.
>
> In the case of process_madvise(), this is fatal, as the operation will stop
> immediately upon this occurring.
>
> By setting PMADV_NO_ERROR_ON_UNMAPPED, the user can indicate that it wishes
> unmapped areas to simply be entirely ignored.
>
> 3. PMADV_SET_FORK_EXEC_DEFAULT
>
> It may be desirable for a user to specify that all VMAs mapped in a process
> address space default to having an madvise() behaviour established by
> default, in such a fashion as that this persists across fork/exec.
>
> Since this is a very powerful option that would make no sense for many
> advice modes, we explicitly only permit known-safe flags here (currently
> MADV_HUGEPAGE and MADV_NOHUGEPAGE only).
>
> 4. PMADV_ENTIRE_ADDRESS_SPACE
>
> It can be annoying, should a user wish to apply madvise() to all VMAs in an
> address space, to have to add a singular large entry to the input iovec.
>
> So provide sugar to permit this - PMADV_ENTIRE_ADDRESS_SPACE. If specified,
> we expect the user to pass NULL and -1 to the vec and vlen parameters
> respectively so they explicitly acknowledge that these will be ignored,
> e.g.:
>
> process_madvise(PIDFD_SELF, NULL, -1, MADV_HUGEPAGE,
> PMADV_ENTIRE_ADDRESS_SPACE | PMADV_SKIP_ERRORS);
>
> Usually a user ought to prefer setting PMADV_SKIP_ERRORS here as it may
> well be the case that incompatible VMAs will be encountered that ought to
> be skipped.
>
> If this is not set, the PMADV_NO_ERROR_ON_UNMAPPED (which was otherwise
> implicitly implied by PMADV_SKIP_ERRORS) ought to be set as of course, the
> entire address space spans at least some gaps.
>
> Lorenzo Stoakes (5):
> mm: madvise: refactor madvise_populate()
> mm/madvise: add PMADV_SKIP_ERRORS process_madvise() flag
> mm/madvise: add PMADV_NO_ERROR_ON_UNMAPPED process_madvise() flag
> mm/madvise: add PMADV_SET_FORK_EXEC_DEFAULT process_madvise() flag
> mm/madvise: add PMADV_ENTIRE_ADDRESS_SPACE process_madvise() flag
>
> include/uapi/asm-generic/mman-common.h | 6 +
> mm/madvise.c | 206 +++++++++++++++++++------
> 2 files changed, 168 insertions(+), 44 deletions(-)
>
> --
> 2.49.0
>
--
Sincerely yours,
Mike.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox