* [PATCH 0/5] Make Rust Binder build as a module
@ 2026-02-05 10:51 Alice Ryhl
2026-02-05 10:51 ` [PATCH 1/5] export file_close_fd and task_work_add Alice Ryhl
` (4 more replies)
0 siblings, 5 replies; 43+ messages in thread
From: Alice Ryhl @ 2026-02-05 10:51 UTC (permalink / raw)
To: Greg Kroah-Hartman, Carlos Llamas
Cc: Alexander Viro, Christian Brauner, Jan Kara, Paul Moore,
James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner,
Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel,
linux-kernel, linux-security-module, linux-mm, rust-for-linux,
Alice Ryhl
Currently Binder only builds as built-in module, but in downstream
Android branches we update the build system to make Rust Binder
buildable as a module. The same situation applies to distros, as there
are many distros that enable Binder for support of apps such as
waydroid, which would benefit from the ability to build Binder as a
module.
Note that although the situation in Android may be temporary - once we
no longer have a C implementation, it makes sense for Rust Binder to be
built-in. But that will both take a while, and in any case, distros
enabling Binder will benefit from it being a module even if Android goes
back to built-in.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
Alice Ryhl (5):
export file_close_fd and task_work_add
security: export binder symbols
mm: export zap_page_range_single and list_lru_add/del
ipc: export init_ipc_ns and put_ipc_ns
rust_binder: mark ANDROID_BINDER_IPC_RUST tristate
drivers/android/Kconfig | 2 +-
fs/file.c | 1 +
ipc/msgutil.c | 1 +
ipc/namespace.c | 1 +
kernel/task_work.c | 1 +
mm/list_lru.c | 2 ++
mm/memory.c | 1 +
security/security.c | 4 ++++
8 files changed, 12 insertions(+), 1 deletion(-)
---
base-commit: 4df29fb5bcebeea28b29386dec18355949512ca1
change-id: 20260204-binder-tristate-729ac021adca
Best regards,
--
Alice Ryhl <aliceryhl@google.com>
^ permalink raw reply [flat|nested] 43+ messages in thread* [PATCH 1/5] export file_close_fd and task_work_add 2026-02-05 10:51 [PATCH 0/5] Make Rust Binder build as a module Alice Ryhl @ 2026-02-05 10:51 ` Alice Ryhl 2026-02-05 11:20 ` Lorenzo Stoakes 2026-02-05 11:38 ` Christian Brauner 2026-02-05 10:51 ` [PATCH 2/5] security: export binder symbols Alice Ryhl ` (3 subsequent siblings) 4 siblings, 2 replies; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 10:51 UTC (permalink / raw) To: Greg Kroah-Hartman, Carlos Llamas Cc: Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Alice Ryhl This exports the functionality needed by Binder to close file descriptors. When you send a fd over Binder, what happens is this: 1. The sending process turns the fd into a struct file and stores it in the transaction object. 2. When the receiving process gets the message, the fd is installed as a fd into the current process. 3. When the receiving process is done handling the message, it tells Binder to clean up the transaction. As part of this, fds embedded in the transaction are closed. Note that it was not always implemented like this. Previously the sending process would install the fd directly into the receiving proc in step 1, but as discussed previously [1] this is not ideal and has since been changed so that fd install happens during receive. The functions being exported here are for closing the fd in step 3. They are required because closing a fd from an ioctl is in general not safe. This is to meet the requirements for using fdget(), which is used by the ioctl framework code before calling into the driver's implementation of the ioctl. Binder works around this with this sequence of operations: 1. file_close_fd() 2. get_file() 3. filp_close() 4. task_work_add(current, TWA_RESUME) 5. <binder returns from ioctl> 6. fput() This ensures that when fput() is called in the task work, the fdget() that the ioctl framework code uses has already been fdput(), so if the fd being closed happens to be the same fd, then the fd is not closed in violation of the fdget() rules. Link: https://lore.kernel.org/all/20180730203633.GC12962@bombadil.infradead.org/ [1] Signed-off-by: Alice Ryhl <aliceryhl@google.com> --- fs/file.c | 1 + kernel/task_work.c | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/file.c b/fs/file.c index 0a4f3bdb2dec6284a0c7b9687213137f2eecb250..0046d0034bf16270cdea7e30a86866ebea3a5a81 100644 --- a/fs/file.c +++ b/fs/file.c @@ -881,6 +881,7 @@ struct file *file_close_fd(unsigned int fd) return file; } +EXPORT_SYMBOL(file_close_fd); void do_close_on_exec(struct files_struct *files) { diff --git a/kernel/task_work.c b/kernel/task_work.c index 0f7519f8e7c93f9a4536c26a341255799c320432..08eb29abaea6b98cc443d1087ddb1d0f1a38c9ae 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -102,6 +102,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, return 0; } +EXPORT_SYMBOL(task_work_add); /** * task_work_cancel_match - cancel a pending work added by task_work_add() -- 2.53.0.rc2.204.g2597b5adb4-goog ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 1/5] export file_close_fd and task_work_add 2026-02-05 10:51 ` [PATCH 1/5] export file_close_fd and task_work_add Alice Ryhl @ 2026-02-05 11:20 ` Lorenzo Stoakes 2026-02-05 11:42 ` Alice Ryhl 2026-02-05 11:38 ` Christian Brauner 1 sibling, 1 reply; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 11:20 UTC (permalink / raw) To: Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 10:51:26AM +0000, Alice Ryhl wrote: > This exports the functionality needed by Binder to close file > descriptors. > > When you send a fd over Binder, what happens is this: > > 1. The sending process turns the fd into a struct file and stores it in > the transaction object. > 2. When the receiving process gets the message, the fd is installed as a > fd into the current process. > 3. When the receiving process is done handling the message, it tells > Binder to clean up the transaction. As part of this, fds embedded in > the transaction are closed. > > Note that it was not always implemented like this. Previously the > sending process would install the fd directly into the receiving proc in > step 1, but as discussed previously [1] this is not ideal and has since > been changed so that fd install happens during receive. > > The functions being exported here are for closing the fd in step 3. They > are required because closing a fd from an ioctl is in general not safe. > This is to meet the requirements for using fdget(), which is used by the > ioctl framework code before calling into the driver's implementation of > the ioctl. Binder works around this with this sequence of operations: > > 1. file_close_fd() > 2. get_file() > 3. filp_close() > 4. task_work_add(current, TWA_RESUME) > 5. <binder returns from ioctl> > 6. fput() > > This ensures that when fput() is called in the task work, the fdget() > that the ioctl framework code uses has already been fdput(), so if the > fd being closed happens to be the same fd, then the fd is not closed > in violation of the fdget() rules. I'm not really familiar with this mechanism but you're already talking about this being a workaround so strikes me the correct thing to do is to find a way to do this in the kernel sensibly rather than exporting internal implementation details and doing it in binder. But on this I defer to Christian and Al. > > Link: https://lore.kernel.org/all/20180730203633.GC12962@bombadil.infradead.org/ [1] > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > --- > fs/file.c | 1 + > kernel/task_work.c | 1 + > 2 files changed, 2 insertions(+) > > diff --git a/fs/file.c b/fs/file.c > index 0a4f3bdb2dec6284a0c7b9687213137f2eecb250..0046d0034bf16270cdea7e30a86866ebea3a5a81 100644 > --- a/fs/file.c > +++ b/fs/file.c > @@ -881,6 +881,7 @@ struct file *file_close_fd(unsigned int fd) > > return file; > } > +EXPORT_SYMBOL(file_close_fd); As a matter of policy we generally don't like to export without GPL like this unless there's a _really_ good reason. Christian or Al may have a different viewpoint but generally this should be an EXPORT_SYMBOL_GPL() and also - there has to be a _really_ good reason to export it. > > void do_close_on_exec(struct files_struct *files) > { > diff --git a/kernel/task_work.c b/kernel/task_work.c > index 0f7519f8e7c93f9a4536c26a341255799c320432..08eb29abaea6b98cc443d1087ddb1d0f1a38c9ae 100644 > --- a/kernel/task_work.c > +++ b/kernel/task_work.c > @@ -102,6 +102,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, > > return 0; > } > +EXPORT_SYMBOL(task_work_add); Same here obviously. There's nothing else exported here so this is even more questionable. We want to export as little as possible, and I'm not modularising a driver, _temporarily_ is a great justification for doing that. Sadly the moment you export something people start using it :) > > /** > * task_work_cancel_match - cancel a pending work added by task_work_add() > > -- > 2.53.0.rc2.204.g2597b5adb4-goog > Cheers, Lorenzo ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 1/5] export file_close_fd and task_work_add 2026-02-05 11:20 ` Lorenzo Stoakes @ 2026-02-05 11:42 ` Alice Ryhl 2026-02-05 11:53 ` Lorenzo Stoakes 0 siblings, 1 reply; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 11:42 UTC (permalink / raw) To: Lorenzo Stoakes Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 11:20:33AM +0000, Lorenzo Stoakes wrote: > On Thu, Feb 05, 2026 at 10:51:26AM +0000, Alice Ryhl wrote: > > This exports the functionality needed by Binder to close file > > descriptors. > > > > When you send a fd over Binder, what happens is this: > > > > 1. The sending process turns the fd into a struct file and stores it in > > the transaction object. > > 2. When the receiving process gets the message, the fd is installed as a > > fd into the current process. > > 3. When the receiving process is done handling the message, it tells > > Binder to clean up the transaction. As part of this, fds embedded in > > the transaction are closed. > > > > Note that it was not always implemented like this. Previously the > > sending process would install the fd directly into the receiving proc in > > step 1, but as discussed previously [1] this is not ideal and has since > > been changed so that fd install happens during receive. > > > > The functions being exported here are for closing the fd in step 3. They > > are required because closing a fd from an ioctl is in general not safe. > > This is to meet the requirements for using fdget(), which is used by the > > ioctl framework code before calling into the driver's implementation of > > the ioctl. Binder works around this with this sequence of operations: > > > > 1. file_close_fd() > > 2. get_file() > > 3. filp_close() > > 4. task_work_add(current, TWA_RESUME) > > 5. <binder returns from ioctl> > > 6. fput() > > > > This ensures that when fput() is called in the task work, the fdget() > > that the ioctl framework code uses has already been fdput(), so if the > > fd being closed happens to be the same fd, then the fd is not closed > > in violation of the fdget() rules. > > I'm not really familiar with this mechanism but you're already talking about > this being a workaround so strikes me the correct thing to do is to find a way > to do this in the kernel sensibly rather than exporting internal implementation > details and doing it in binder. I did previously submit a patch that implemented this logic outside of Binder, but I was advised to move it into Binder. But I'm happy to submit a patch to extract this logic into some sort of close_fd_safe() method that can be called even if said fd is currently held using fdget(). > > Link: https://lore.kernel.org/all/20180730203633.GC12962@bombadil.infradead.org/ [1] > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > --- > > fs/file.c | 1 + > > kernel/task_work.c | 1 + > > 2 files changed, 2 insertions(+) > > > > diff --git a/fs/file.c b/fs/file.c > > index 0a4f3bdb2dec6284a0c7b9687213137f2eecb250..0046d0034bf16270cdea7e30a86866ebea3a5a81 100644 > > --- a/fs/file.c > > +++ b/fs/file.c > > @@ -881,6 +881,7 @@ struct file *file_close_fd(unsigned int fd) > > > > return file; > > } > > +EXPORT_SYMBOL(file_close_fd); > > As a matter of policy we generally don't like to export without GPL like this > unless there's a _really_ good reason. > > Christian or Al may have a different viewpoint but generally this should be an > EXPORT_SYMBOL_GPL() and also - there has to be a _really_ good reason to export > it. Sorry I should just have done _GPL from the beginning. My mistake. Alice ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 1/5] export file_close_fd and task_work_add 2026-02-05 11:42 ` Alice Ryhl @ 2026-02-05 11:53 ` Lorenzo Stoakes 2026-02-05 13:45 ` Alice Ryhl 0 siblings, 1 reply; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 11:53 UTC (permalink / raw) To: Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 11:42:46AM +0000, Alice Ryhl wrote: > On Thu, Feb 05, 2026 at 11:20:33AM +0000, Lorenzo Stoakes wrote: > > On Thu, Feb 05, 2026 at 10:51:26AM +0000, Alice Ryhl wrote: > > > This exports the functionality needed by Binder to close file > > > descriptors. > > > > > > When you send a fd over Binder, what happens is this: > > > > > > 1. The sending process turns the fd into a struct file and stores it in > > > the transaction object. > > > 2. When the receiving process gets the message, the fd is installed as a > > > fd into the current process. > > > 3. When the receiving process is done handling the message, it tells > > > Binder to clean up the transaction. As part of this, fds embedded in > > > the transaction are closed. > > > > > > Note that it was not always implemented like this. Previously the > > > sending process would install the fd directly into the receiving proc in > > > step 1, but as discussed previously [1] this is not ideal and has since > > > been changed so that fd install happens during receive. > > > > > > The functions being exported here are for closing the fd in step 3. They > > > are required because closing a fd from an ioctl is in general not safe. > > > This is to meet the requirements for using fdget(), which is used by the > > > ioctl framework code before calling into the driver's implementation of > > > the ioctl. Binder works around this with this sequence of operations: > > > > > > 1. file_close_fd() > > > 2. get_file() > > > 3. filp_close() > > > 4. task_work_add(current, TWA_RESUME) > > > 5. <binder returns from ioctl> > > > 6. fput() > > > > > > This ensures that when fput() is called in the task work, the fdget() > > > that the ioctl framework code uses has already been fdput(), so if the > > > fd being closed happens to be the same fd, then the fd is not closed > > > in violation of the fdget() rules. > > > > I'm not really familiar with this mechanism but you're already talking about > > this being a workaround so strikes me the correct thing to do is to find a way > > to do this in the kernel sensibly rather than exporting internal implementation > > details and doing it in binder. > > I did previously submit a patch that implemented this logic outside of > Binder, but I was advised to move it into Binder. Right yeah that's just odd to me, we really do not want to be adding internal implementation details to drivers. This is based on bitter experience of bugs being caused by drivers abusing every interface they get, which is basically exactly what always happens, sadly. And out-of-tree is heavily discouraged. Also can we use EXPORT_SYMBOL_FOR_MODULES() for anything we do need to export to make it explicitly only for binder, perhaps? > > But I'm happy to submit a patch to extract this logic into some sort of > close_fd_safe() method that can be called even if said fd is currently > held using fdget(). Yup, especially given Christian's view on the kernel task export here I think that's a more sensible approach. But obviously I defer the sensible-ness of this to him as I am but an mm dev :) > > > > Link: https://lore.kernel.org/all/20180730203633.GC12962@bombadil.infradead.org/ [1] > > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > > --- > > > fs/file.c | 1 + > > > kernel/task_work.c | 1 + > > > 2 files changed, 2 insertions(+) > > > > > > diff --git a/fs/file.c b/fs/file.c > > > index 0a4f3bdb2dec6284a0c7b9687213137f2eecb250..0046d0034bf16270cdea7e30a86866ebea3a5a81 100644 > > > --- a/fs/file.c > > > +++ b/fs/file.c > > > @@ -881,6 +881,7 @@ struct file *file_close_fd(unsigned int fd) > > > > > > return file; > > > } > > > +EXPORT_SYMBOL(file_close_fd); > > > > As a matter of policy we generally don't like to export without GPL like this > > unless there's a _really_ good reason. > > > > Christian or Al may have a different viewpoint but generally this should be an > > EXPORT_SYMBOL_GPL() and also - there has to be a _really_ good reason to export > > it. > > Sorry I should just have done _GPL from the beginning. My mistake. Thanks! > > Alice Cheers, Lorenzo ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 1/5] export file_close_fd and task_work_add 2026-02-05 11:53 ` Lorenzo Stoakes @ 2026-02-05 13:45 ` Alice Ryhl 2026-02-09 15:21 ` Lorenzo Stoakes 0 siblings, 1 reply; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 13:45 UTC (permalink / raw) To: Lorenzo Stoakes Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 11:53:19AM +0000, Lorenzo Stoakes wrote: > On Thu, Feb 05, 2026 at 11:42:46AM +0000, Alice Ryhl wrote: > > On Thu, Feb 05, 2026 at 11:20:33AM +0000, Lorenzo Stoakes wrote: > > > On Thu, Feb 05, 2026 at 10:51:26AM +0000, Alice Ryhl wrote: > > > > This exports the functionality needed by Binder to close file > > > > descriptors. > > > > > > > > When you send a fd over Binder, what happens is this: > > > > > > > > 1. The sending process turns the fd into a struct file and stores it in > > > > the transaction object. > > > > 2. When the receiving process gets the message, the fd is installed as a > > > > fd into the current process. > > > > 3. When the receiving process is done handling the message, it tells > > > > Binder to clean up the transaction. As part of this, fds embedded in > > > > the transaction are closed. > > > > > > > > Note that it was not always implemented like this. Previously the > > > > sending process would install the fd directly into the receiving proc in > > > > step 1, but as discussed previously [1] this is not ideal and has since > > > > been changed so that fd install happens during receive. > > > > > > > > The functions being exported here are for closing the fd in step 3. They > > > > are required because closing a fd from an ioctl is in general not safe. > > > > This is to meet the requirements for using fdget(), which is used by the > > > > ioctl framework code before calling into the driver's implementation of > > > > the ioctl. Binder works around this with this sequence of operations: > > > > > > > > 1. file_close_fd() > > > > 2. get_file() > > > > 3. filp_close() > > > > 4. task_work_add(current, TWA_RESUME) > > > > 5. <binder returns from ioctl> > > > > 6. fput() > > > > > > > > This ensures that when fput() is called in the task work, the fdget() > > > > that the ioctl framework code uses has already been fdput(), so if the > > > > fd being closed happens to be the same fd, then the fd is not closed > > > > in violation of the fdget() rules. > > > > > > I'm not really familiar with this mechanism but you're already talking about > > > this being a workaround so strikes me the correct thing to do is to find a way > > > to do this in the kernel sensibly rather than exporting internal implementation > > > details and doing it in binder. > > > > I did previously submit a patch that implemented this logic outside of > > Binder, but I was advised to move it into Binder. > > Right yeah that's just odd to me, we really do not want to be adding internal > implementation details to drivers. > > This is based on bitter experience of bugs being caused by drivers abusing every > interface they get, which is basically exactly what always happens, sadly. > > And out-of-tree is heavily discouraged. > > Also can we use EXPORT_SYMBOL_FOR_MODULES() for anything we do need to export to > make it explicitly only for binder, perhaps? > > > > > But I'm happy to submit a patch to extract this logic into some sort of > > close_fd_safe() method that can be called even if said fd is currently > > held using fdget(). > > Yup, especially given Christian's view on the kernel task export here I think > that's a more sensible approach. > > But obviously I defer the sensible-ness of this to him as I am but an mm dev :) Quick sketch of how this would look: diff --git a/drivers/android/binder.c b/drivers/android/binder.c index adde1e40cccd..6fb7175ff69b 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -64,7 +64,6 @@ #include <linux/spinlock.h> #include <linux/ratelimit.h> #include <linux/syscalls.h> -#include <linux/task_work.h> #include <linux/sizes.h> #include <linux/ktime.h> @@ -1962,68 +1961,6 @@ static bool binder_validate_fixup(struct binder_proc *proc, return (fixup_offset >= last_min_offset); } -/** - * struct binder_task_work_cb - for deferred close - * - * @twork: callback_head for task work - * @file: file to close - * - * Structure to pass task work to be handled after - * returning from binder_ioctl() via task_work_add(). - */ -struct binder_task_work_cb { - struct callback_head twork; - struct file *file; -}; - -/** - * binder_do_fd_close() - close list of file descriptors - * @twork: callback head for task work - * - * It is not safe to call ksys_close() during the binder_ioctl() - * function if there is a chance that binder's own file descriptor - * might be closed. This is to meet the requirements for using - * fdget() (see comments for __fget_light()). Therefore use - * task_work_add() to schedule the close operation once we have - * returned from binder_ioctl(). This function is a callback - * for that mechanism and does the actual ksys_close() on the - * given file descriptor. - */ -static void binder_do_fd_close(struct callback_head *twork) -{ - struct binder_task_work_cb *twcb = container_of(twork, - struct binder_task_work_cb, twork); - - fput(twcb->file); - kfree(twcb); -} - -/** - * binder_deferred_fd_close() - schedule a close for the given file-descriptor - * @fd: file-descriptor to close - * - * See comments in binder_do_fd_close(). This function is used to schedule - * a file-descriptor to be closed after returning from binder_ioctl(). - */ -static void binder_deferred_fd_close(int fd) -{ - struct binder_task_work_cb *twcb; - - twcb = kzalloc(sizeof(*twcb), GFP_KERNEL); - if (!twcb) - return; - init_task_work(&twcb->twork, binder_do_fd_close); - twcb->file = file_close_fd(fd); - if (twcb->file) { - // pin it until binder_do_fd_close(); see comments there - get_file(twcb->file); - filp_close(twcb->file, current->files); - task_work_add(current, &twcb->twork, TWA_RESUME); - } else { - kfree(twcb); - } -} - static void binder_transaction_buffer_release(struct binder_proc *proc, struct binder_thread *thread, struct binder_buffer *buffer, @@ -2183,7 +2120,10 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, offset, sizeof(fd)); WARN_ON(err); if (!err) { - binder_deferred_fd_close(fd); + /* + * Intentionally ignore EBADF errors here. + */ + close_fd_safe(fd, GFP_KERNEL | __GFP_NOFAIL); /* * Need to make sure the thread goes * back to userspace to complete the diff --git a/fs/file.c b/fs/file.c index 0a4f3bdb2dec..58e3825e846c 100644 --- a/fs/file.c +++ b/fs/file.c @@ -21,6 +21,7 @@ #include <linux/rcupdate.h> #include <linux/close_range.h> #include <linux/file_ref.h> +#include <linux/task_work.h> #include <net/sock.h> #include <linux/init_task.h> @@ -1525,3 +1526,47 @@ int iterate_fd(struct files_struct *files, unsigned n, return res; } EXPORT_SYMBOL(iterate_fd); + +struct close_fd_safe_task_work { + struct callback_head twork; + struct file *file; +}; + +static void close_fd_safe_callback(struct callback_head *twork) +{ + struct close_fd_safe_task_work *twcb = container_of(twork, + struct close_fd_safe_task_work, twork); + + fput(twcb->file); + kfree(twcb); +} + +/** + * close_fd_safe - close the given fd + * @fd: file descriptor to close + * @flags: gfp flags for allocation of task work + * + * This closes an fd. Unlike close_fd(), this may be used even if the fd is + * currently held with fdget(). + * + * Returns: 0 or an error code + */ +int close_fd_safe(unsigned int fd, gfp_t flags) +{ + struct close_fd_safe_task_work *twcb; + + twcb = kzalloc(sizeof(*twcb), flags); + if (!twcb) + return -ENOMEM; + init_task_work(&twcb->twork, close_fd_safe_callback); + twcb->file = file_close_fd(fd); + if (!twcb->file) { + kfree(twcb); + return -EBADF; + } + + get_file(twcb->file); + filp_close(twcb->file, current->files); + task_work_add(current, &twcb->twork, TWA_RESUME); + return 0; +} diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index c45306a9f007..1c99a56c0cdf 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -111,6 +111,7 @@ int iterate_fd(struct files_struct *, unsigned, const void *); extern int close_fd(unsigned int fd); +extern int close_fd_safe(unsigned int fd, gfp_t flags); extern struct file *file_close_fd(unsigned int fd); extern struct kmem_cache *files_cachep; ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 1/5] export file_close_fd and task_work_add 2026-02-05 13:45 ` Alice Ryhl @ 2026-02-09 15:21 ` Lorenzo Stoakes 2026-02-10 8:47 ` Alice Ryhl 0 siblings, 1 reply; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-09 15:21 UTC (permalink / raw) To: Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 01:45:40PM +0000, Alice Ryhl wrote: > On Thu, Feb 05, 2026 at 11:53:19AM +0000, Lorenzo Stoakes wrote: > > On Thu, Feb 05, 2026 at 11:42:46AM +0000, Alice Ryhl wrote: > > > On Thu, Feb 05, 2026 at 11:20:33AM +0000, Lorenzo Stoakes wrote: > > > > On Thu, Feb 05, 2026 at 10:51:26AM +0000, Alice Ryhl wrote: > > > > > This exports the functionality needed by Binder to close file > > > > > descriptors. > > > > > > > > > > When you send a fd over Binder, what happens is this: > > > > > > > > > > 1. The sending process turns the fd into a struct file and stores it in > > > > > the transaction object. > > > > > 2. When the receiving process gets the message, the fd is installed as a > > > > > fd into the current process. > > > > > 3. When the receiving process is done handling the message, it tells > > > > > Binder to clean up the transaction. As part of this, fds embedded in > > > > > the transaction are closed. > > > > > > > > > > Note that it was not always implemented like this. Previously the > > > > > sending process would install the fd directly into the receiving proc in > > > > > step 1, but as discussed previously [1] this is not ideal and has since > > > > > been changed so that fd install happens during receive. > > > > > > > > > > The functions being exported here are for closing the fd in step 3. They > > > > > are required because closing a fd from an ioctl is in general not safe. > > > > > This is to meet the requirements for using fdget(), which is used by the > > > > > ioctl framework code before calling into the driver's implementation of > > > > > the ioctl. Binder works around this with this sequence of operations: > > > > > > > > > > 1. file_close_fd() > > > > > 2. get_file() > > > > > 3. filp_close() > > > > > 4. task_work_add(current, TWA_RESUME) > > > > > 5. <binder returns from ioctl> > > > > > 6. fput() > > > > > > > > > > This ensures that when fput() is called in the task work, the fdget() > > > > > that the ioctl framework code uses has already been fdput(), so if the > > > > > fd being closed happens to be the same fd, then the fd is not closed > > > > > in violation of the fdget() rules. > > > > > > > > I'm not really familiar with this mechanism but you're already talking about > > > > this being a workaround so strikes me the correct thing to do is to find a way > > > > to do this in the kernel sensibly rather than exporting internal implementation > > > > details and doing it in binder. > > > > > > I did previously submit a patch that implemented this logic outside of > > > Binder, but I was advised to move it into Binder. > > > > Right yeah that's just odd to me, we really do not want to be adding internal > > implementation details to drivers. > > > > This is based on bitter experience of bugs being caused by drivers abusing every > > interface they get, which is basically exactly what always happens, sadly. > > > > And out-of-tree is heavily discouraged. > > > > Also can we use EXPORT_SYMBOL_FOR_MODULES() for anything we do need to export to > > make it explicitly only for binder, perhaps? > > > > > > > > But I'm happy to submit a patch to extract this logic into some sort of > > > close_fd_safe() method that can be called even if said fd is currently > > > held using fdget(). > > > > Yup, especially given Christian's view on the kernel task export here I think > > that's a more sensible approach. > > > > But obviously I defer the sensible-ness of this to him as I am but an mm dev :) > > Quick sketch of how this would look: > > diff --git a/drivers/android/binder.c b/drivers/android/binder.c > index adde1e40cccd..6fb7175ff69b 100644 > --- a/drivers/android/binder.c > +++ b/drivers/android/binder.c > @@ -64,7 +64,6 @@ > #include <linux/spinlock.h> > #include <linux/ratelimit.h> > #include <linux/syscalls.h> > -#include <linux/task_work.h> > #include <linux/sizes.h> > #include <linux/ktime.h> > > @@ -1962,68 +1961,6 @@ static bool binder_validate_fixup(struct binder_proc *proc, > return (fixup_offset >= last_min_offset); > } > > -/** > - * struct binder_task_work_cb - for deferred close > - * > - * @twork: callback_head for task work > - * @file: file to close > - * > - * Structure to pass task work to be handled after > - * returning from binder_ioctl() via task_work_add(). > - */ > -struct binder_task_work_cb { > - struct callback_head twork; > - struct file *file; > -}; > - > -/** > - * binder_do_fd_close() - close list of file descriptors > - * @twork: callback head for task work > - * > - * It is not safe to call ksys_close() during the binder_ioctl() > - * function if there is a chance that binder's own file descriptor > - * might be closed. This is to meet the requirements for using > - * fdget() (see comments for __fget_light()). Therefore use > - * task_work_add() to schedule the close operation once we have > - * returned from binder_ioctl(). This function is a callback > - * for that mechanism and does the actual ksys_close() on the > - * given file descriptor. > - */ > -static void binder_do_fd_close(struct callback_head *twork) > -{ > - struct binder_task_work_cb *twcb = container_of(twork, > - struct binder_task_work_cb, twork); > - > - fput(twcb->file); > - kfree(twcb); > -} > - > -/** > - * binder_deferred_fd_close() - schedule a close for the given file-descriptor > - * @fd: file-descriptor to close > - * > - * See comments in binder_do_fd_close(). This function is used to schedule > - * a file-descriptor to be closed after returning from binder_ioctl(). > - */ > -static void binder_deferred_fd_close(int fd) > -{ > - struct binder_task_work_cb *twcb; > - > - twcb = kzalloc(sizeof(*twcb), GFP_KERNEL); > - if (!twcb) > - return; > - init_task_work(&twcb->twork, binder_do_fd_close); > - twcb->file = file_close_fd(fd); > - if (twcb->file) { > - // pin it until binder_do_fd_close(); see comments there > - get_file(twcb->file); > - filp_close(twcb->file, current->files); > - task_work_add(current, &twcb->twork, TWA_RESUME); > - } else { > - kfree(twcb); > - } > -} > - > static void binder_transaction_buffer_release(struct binder_proc *proc, > struct binder_thread *thread, > struct binder_buffer *buffer, > @@ -2183,7 +2120,10 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, > offset, sizeof(fd)); > WARN_ON(err); > if (!err) { > - binder_deferred_fd_close(fd); > + /* > + * Intentionally ignore EBADF errors here. > + */ > + close_fd_safe(fd, GFP_KERNEL | __GFP_NOFAIL); > /* > * Need to make sure the thread goes > * back to userspace to complete the > diff --git a/fs/file.c b/fs/file.c > index 0a4f3bdb2dec..58e3825e846c 100644 > --- a/fs/file.c > +++ b/fs/file.c > @@ -21,6 +21,7 @@ > #include <linux/rcupdate.h> > #include <linux/close_range.h> > #include <linux/file_ref.h> > +#include <linux/task_work.h> > #include <net/sock.h> > #include <linux/init_task.h> > > @@ -1525,3 +1526,47 @@ int iterate_fd(struct files_struct *files, unsigned n, > return res; > } > EXPORT_SYMBOL(iterate_fd); > + > +struct close_fd_safe_task_work { > + struct callback_head twork; > + struct file *file; > +}; > + > +static void close_fd_safe_callback(struct callback_head *twork) > +{ > + struct close_fd_safe_task_work *twcb = container_of(twork, > + struct close_fd_safe_task_work, twork); > + > + fput(twcb->file); > + kfree(twcb); > +} > + > +/** > + * close_fd_safe - close the given fd > + * @fd: file descriptor to close > + * @flags: gfp flags for allocation of task work > + * > + * This closes an fd. Unlike close_fd(), this may be used even if the fd is > + * currently held with fdget(). > + * > + * Returns: 0 or an error code > + */ > +int close_fd_safe(unsigned int fd, gfp_t flags) > +{ > + struct close_fd_safe_task_work *twcb; > + > + twcb = kzalloc(sizeof(*twcb), flags); > + if (!twcb) > + return -ENOMEM; > + init_task_work(&twcb->twork, close_fd_safe_callback); > + twcb->file = file_close_fd(fd); > + if (!twcb->file) { > + kfree(twcb); > + return -EBADF; > + } > + > + get_file(twcb->file); > + filp_close(twcb->file, current->files); > + task_work_add(current, &twcb->twork, TWA_RESUME); > + return 0; > +} Would need an EXPORT_SYMBOL_FOR_MODULES(...) here right? > diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h > index c45306a9f007..1c99a56c0cdf 100644 > --- a/include/linux/fdtable.h > +++ b/include/linux/fdtable.h > @@ -111,6 +111,7 @@ int iterate_fd(struct files_struct *, unsigned, > const void *); > > extern int close_fd(unsigned int fd); > +extern int close_fd_safe(unsigned int fd, gfp_t flags); One nit, generally well in mm anyway we avoid the 'extern' and remove them as we go. Not sure about vfs actually though? > extern struct file *file_close_fd(unsigned int fd); > > extern struct kmem_cache *files_cachep; I mean this is essentially taking what's in binder and making it a general thing, so needs Christian's input on whether this is sensible I think :) Cheers, Lorenzo ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 1/5] export file_close_fd and task_work_add 2026-02-09 15:21 ` Lorenzo Stoakes @ 2026-02-10 8:47 ` Alice Ryhl 0 siblings, 0 replies; 43+ messages in thread From: Alice Ryhl @ 2026-02-10 8:47 UTC (permalink / raw) To: Lorenzo Stoakes Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Mon, Feb 09, 2026 at 03:21:58PM +0000, Lorenzo Stoakes wrote: > On Thu, Feb 05, 2026 at 01:45:40PM +0000, Alice Ryhl wrote: > > +/** > > + * close_fd_safe - close the given fd > > + * @fd: file descriptor to close > > + * @flags: gfp flags for allocation of task work > > + * > > + * This closes an fd. Unlike close_fd(), this may be used even if the fd is > > + * currently held with fdget(). > > + * > > + * Returns: 0 or an error code > > + */ > > +int close_fd_safe(unsigned int fd, gfp_t flags) > > +{ > > + struct close_fd_safe_task_work *twcb; > > + > > + twcb = kzalloc(sizeof(*twcb), flags); > > + if (!twcb) > > + return -ENOMEM; > > + init_task_work(&twcb->twork, close_fd_safe_callback); > > + twcb->file = file_close_fd(fd); > > + if (!twcb->file) { > > + kfree(twcb); > > + return -EBADF; > > + } > > + > > + get_file(twcb->file); > > + filp_close(twcb->file, current->files); > > + task_work_add(current, &twcb->twork, TWA_RESUME); > > + return 0; > > +} > > Would need an EXPORT_SYMBOL_FOR_MODULES(...) here right? Ah yeah, for Binder to become a module it would need to be exported. (Though maybe it's worth moving this logic even if Binder is not made into a module?) > > diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h > > index c45306a9f007..1c99a56c0cdf 100644 > > --- a/include/linux/fdtable.h > > +++ b/include/linux/fdtable.h > > @@ -111,6 +111,7 @@ int iterate_fd(struct files_struct *, unsigned, > > const void *); > > > > extern int close_fd(unsigned int fd); > > +extern int close_fd_safe(unsigned int fd, gfp_t flags); > > One nit, generally well in mm anyway we avoid the 'extern' and remove them as we > go. Not sure about vfs actually though? Right. Not sure about this. > > extern struct file *file_close_fd(unsigned int fd); > > > > extern struct kmem_cache *files_cachep; > > I mean this is essentially taking what's in binder and making it a general > thing, so needs Christian's input on whether this is sensible I think :) Yeah. Alice ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 1/5] export file_close_fd and task_work_add 2026-02-05 10:51 ` [PATCH 1/5] export file_close_fd and task_work_add Alice Ryhl 2026-02-05 11:20 ` Lorenzo Stoakes @ 2026-02-05 11:38 ` Christian Brauner 2026-02-05 11:52 ` Jan Kara 1 sibling, 1 reply; 43+ messages in thread From: Christian Brauner @ 2026-02-05 11:38 UTC (permalink / raw) To: Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Christoph Hellwig On Thu, Feb 05, 2026 at 10:51:26AM +0000, Alice Ryhl wrote: > This exports the functionality needed by Binder to close file > descriptors. > > When you send a fd over Binder, what happens is this: > > 1. The sending process turns the fd into a struct file and stores it in > the transaction object. > 2. When the receiving process gets the message, the fd is installed as a > fd into the current process. > 3. When the receiving process is done handling the message, it tells > Binder to clean up the transaction. As part of this, fds embedded in > the transaction are closed. > > Note that it was not always implemented like this. Previously the > sending process would install the fd directly into the receiving proc in > step 1, but as discussed previously [1] this is not ideal and has since > been changed so that fd install happens during receive. > > The functions being exported here are for closing the fd in step 3. They > are required because closing a fd from an ioctl is in general not safe. > This is to meet the requirements for using fdget(), which is used by the > ioctl framework code before calling into the driver's implementation of > the ioctl. Binder works around this with this sequence of operations: > > 1. file_close_fd() > 2. get_file() > 3. filp_close() > 4. task_work_add(current, TWA_RESUME) > 5. <binder returns from ioctl> > 6. fput() > > This ensures that when fput() is called in the task work, the fdget() > that the ioctl framework code uses has already been fdput(), so if the > fd being closed happens to be the same fd, then the fd is not closed > in violation of the fdget() rules. > > Link: https://lore.kernel.org/all/20180730203633.GC12962@bombadil.infradead.org/ [1] > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > --- > fs/file.c | 1 + > kernel/task_work.c | 1 + > 2 files changed, 2 insertions(+) > > diff --git a/fs/file.c b/fs/file.c > index 0a4f3bdb2dec6284a0c7b9687213137f2eecb250..0046d0034bf16270cdea7e30a86866ebea3a5a81 100644 > --- a/fs/file.c > +++ b/fs/file.c > @@ -881,6 +881,7 @@ struct file *file_close_fd(unsigned int fd) > > return file; > } > +EXPORT_SYMBOL(file_close_fd); > > void do_close_on_exec(struct files_struct *files) > { > diff --git a/kernel/task_work.c b/kernel/task_work.c > index 0f7519f8e7c93f9a4536c26a341255799c320432..08eb29abaea6b98cc443d1087ddb1d0f1a38c9ae 100644 > --- a/kernel/task_work.c > +++ b/kernel/task_work.c > @@ -102,6 +102,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, > > return 0; > } > +EXPORT_SYMBOL(task_work_add); Uhm, no. We're not going to export task_work_add() to let random drivers queue up work for a task when it returns to userspace. That just screams bugs and deadlocks at full capacity. Sorry, no. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 1/5] export file_close_fd and task_work_add 2026-02-05 11:38 ` Christian Brauner @ 2026-02-05 11:52 ` Jan Kara 2026-02-05 12:07 ` Alice Ryhl 0 siblings, 1 reply; 43+ messages in thread From: Jan Kara @ 2026-02-05 11:52 UTC (permalink / raw) To: Christian Brauner Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Christoph Hellwig On Thu 05-02-26 12:38:22, Christian Brauner wrote: > On Thu, Feb 05, 2026 at 10:51:26AM +0000, Alice Ryhl wrote: > > This exports the functionality needed by Binder to close file > > descriptors. > > > > When you send a fd over Binder, what happens is this: > > > > 1. The sending process turns the fd into a struct file and stores it in > > the transaction object. > > 2. When the receiving process gets the message, the fd is installed as a > > fd into the current process. > > 3. When the receiving process is done handling the message, it tells > > Binder to clean up the transaction. As part of this, fds embedded in > > the transaction are closed. > > > > Note that it was not always implemented like this. Previously the > > sending process would install the fd directly into the receiving proc in > > step 1, but as discussed previously [1] this is not ideal and has since > > been changed so that fd install happens during receive. > > > > The functions being exported here are for closing the fd in step 3. They > > are required because closing a fd from an ioctl is in general not safe. > > This is to meet the requirements for using fdget(), which is used by the > > ioctl framework code before calling into the driver's implementation of > > the ioctl. Binder works around this with this sequence of operations: > > > > 1. file_close_fd() > > 2. get_file() > > 3. filp_close() > > 4. task_work_add(current, TWA_RESUME) > > 5. <binder returns from ioctl> > > 6. fput() > > > > This ensures that when fput() is called in the task work, the fdget() > > that the ioctl framework code uses has already been fdput(), so if the > > fd being closed happens to be the same fd, then the fd is not closed > > in violation of the fdget() rules. > > > > Link: https://lore.kernel.org/all/20180730203633.GC12962@bombadil.infradead.org/ [1] > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > --- > > fs/file.c | 1 + > > kernel/task_work.c | 1 + > > 2 files changed, 2 insertions(+) > > > > diff --git a/fs/file.c b/fs/file.c > > index 0a4f3bdb2dec6284a0c7b9687213137f2eecb250..0046d0034bf16270cdea7e30a86866ebea3a5a81 100644 > > --- a/fs/file.c > > +++ b/fs/file.c > > @@ -881,6 +881,7 @@ struct file *file_close_fd(unsigned int fd) > > > > return file; > > } > > +EXPORT_SYMBOL(file_close_fd); > > > > void do_close_on_exec(struct files_struct *files) > > { > > diff --git a/kernel/task_work.c b/kernel/task_work.c > > index 0f7519f8e7c93f9a4536c26a341255799c320432..08eb29abaea6b98cc443d1087ddb1d0f1a38c9ae 100644 > > --- a/kernel/task_work.c > > +++ b/kernel/task_work.c > > @@ -102,6 +102,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, > > > > return 0; > > } > > +EXPORT_SYMBOL(task_work_add); > > Uhm, no. We're not going to export task_work_add() to let random drivers > queue up work for a task when it returns to userspace. That just screams > bugs and deadlocks at full capacity. Sorry, no. Agreed. And just to demonstrate the point binder's use would become the first of such bugs because it is prone to the module being removed while the task work is in flight and thus do_close_fd() code can be freed by the time it gets executed. Generally, making some code modular usually requires more effort than just flipping the Kconfig to tristate. You usually need to make sure all objects and queued work is flushed before the module can be removed. Not sure how much of this is taken care of by Rust though... Honza -- Jan Kara <jack@suse.com> SUSE Labs, CR ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 1/5] export file_close_fd and task_work_add 2026-02-05 11:52 ` Jan Kara @ 2026-02-05 12:07 ` Alice Ryhl 0 siblings, 0 replies; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 12:07 UTC (permalink / raw) To: Jan Kara Cc: Christian Brauner, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Christoph Hellwig On Thu, Feb 05, 2026 at 12:52:37PM +0100, Jan Kara wrote: > > Agreed. And just to demonstrate the point binder's use would become the > first of such bugs because it is prone to the module being removed while > the task work is in flight and thus do_close_fd() code can be freed by the > time it gets executed. Good point ... > Generally, making some code modular usually requires more effort than just > flipping the Kconfig to tristate. You usually need to make sure all objects > and queued work is flushed before the module can be removed. Not sure how > much of this is taken care of by Rust though... > > Honza > -- > Jan Kara <jack@suse.com> > SUSE Labs, CR ^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 2/5] security: export binder symbols 2026-02-05 10:51 [PATCH 0/5] Make Rust Binder build as a module Alice Ryhl 2026-02-05 10:51 ` [PATCH 1/5] export file_close_fd and task_work_add Alice Ryhl @ 2026-02-05 10:51 ` Alice Ryhl 2026-02-20 0:00 ` Paul Moore 2026-02-05 10:51 ` [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del Alice Ryhl ` (2 subsequent siblings) 4 siblings, 1 reply; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 10:51 UTC (permalink / raw) To: Greg Kroah-Hartman, Carlos Llamas Cc: Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Alice Ryhl To enable building Binder as a module, export these symbols. Signed-off-by: Alice Ryhl <aliceryhl@google.com> --- security/security.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/security/security.c b/security/security.c index 31a688650601b62df1e536bbe4407817edbd6707..b4776f0e25b33df95379a08a7659c0e5f767237b 100644 --- a/security/security.c +++ b/security/security.c @@ -488,6 +488,7 @@ int security_binder_set_context_mgr(const struct cred *mgr) { return call_int_hook(binder_set_context_mgr, mgr); } +EXPORT_SYMBOL_GPL(security_binder_set_context_mgr); /** * security_binder_transaction() - Check if a binder transaction is allowed @@ -503,6 +504,7 @@ int security_binder_transaction(const struct cred *from, { return call_int_hook(binder_transaction, from, to); } +EXPORT_SYMBOL_GPL(security_binder_transaction); /** * security_binder_transfer_binder() - Check if a binder transfer is allowed @@ -518,6 +520,7 @@ int security_binder_transfer_binder(const struct cred *from, { return call_int_hook(binder_transfer_binder, from, to); } +EXPORT_SYMBOL_GPL(security_binder_transfer_binder); /** * security_binder_transfer_file() - Check if a binder file xfer is allowed @@ -534,6 +537,7 @@ int security_binder_transfer_file(const struct cred *from, { return call_int_hook(binder_transfer_file, from, to, file); } +EXPORT_SYMBOL_GPL(security_binder_transfer_file); /** * security_ptrace_access_check() - Check if tracing is allowed -- 2.53.0.rc2.204.g2597b5adb4-goog ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 2/5] security: export binder symbols 2026-02-05 10:51 ` [PATCH 2/5] security: export binder symbols Alice Ryhl @ 2026-02-20 0:00 ` Paul Moore 0 siblings, 0 replies; 43+ messages in thread From: Paul Moore @ 2026-02-20 0:00 UTC (permalink / raw) To: Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 5, 2026 at 5:51 AM Alice Ryhl <aliceryhl@google.com> wrote: > > To enable building Binder as a module, export these symbols. > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > --- > security/security.c | 4 ++++ > 1 file changed, 4 insertions(+) Acked-by: Paul Moore <paul@paul-moore.com> -- paul-moore.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 10:51 [PATCH 0/5] Make Rust Binder build as a module Alice Ryhl 2026-02-05 10:51 ` [PATCH 1/5] export file_close_fd and task_work_add Alice Ryhl 2026-02-05 10:51 ` [PATCH 2/5] security: export binder symbols Alice Ryhl @ 2026-02-05 10:51 ` Alice Ryhl 2026-02-05 10:59 ` David Hildenbrand (arm) 2026-02-05 11:29 ` Lorenzo Stoakes 2026-02-05 10:51 ` [PATCH 4/5] ipc: export init_ipc_ns and put_ipc_ns Alice Ryhl 2026-02-05 10:51 ` [PATCH 5/5] rust_binder: mark ANDROID_BINDER_IPC_RUST tristate Alice Ryhl 4 siblings, 2 replies; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 10:51 UTC (permalink / raw) To: Greg Kroah-Hartman, Carlos Llamas Cc: Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Alice Ryhl These are the functions needed by Binder's shrinker. Binder uses zap_page_range_single in the shrinker path to remove an unused page from the mmap'd region. Note that pages are only removed from the mmap'd region lazily when shrinker asks for it. Binder uses list_lru_add/del to keep track of the shrinker lru list, and it can't use _obj because the list head is not stored inline in the page actually being lru freed, so page_to_nid(virt_to_page(item)) on the list head computes the nid of the wrong page. Signed-off-by: Alice Ryhl <aliceryhl@google.com> --- mm/list_lru.c | 2 ++ mm/memory.c | 1 + 2 files changed, 3 insertions(+) diff --git a/mm/list_lru.c b/mm/list_lru.c index ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, unlock_list_lru(l, false); return false; } +EXPORT_SYMBOL_GPL(list_lru_add); bool list_lru_add_obj(struct list_lru *lru, struct list_head *item) { @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, unlock_list_lru(l, false); return false; } +EXPORT_SYMBOL_GPL(list_lru_del); bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) { diff --git a/mm/memory.c b/mm/memory.c index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, zap_page_range_single_batched(&tlb, vma, address, size, details); tlb_finish_mmu(&tlb); } +EXPORT_SYMBOL(zap_page_range_single); /** * zap_vma_ptes - remove ptes mapping the vma -- 2.53.0.rc2.204.g2597b5adb4-goog ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 10:51 ` [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del Alice Ryhl @ 2026-02-05 10:59 ` David Hildenbrand (arm) 2026-02-05 11:04 ` Alice Ryhl 2026-02-05 11:29 ` Lorenzo Stoakes 1 sibling, 1 reply; 43+ messages in thread From: David Hildenbrand (arm) @ 2026-02-05 10:59 UTC (permalink / raw) To: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas Cc: Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On 2/5/26 11:51, Alice Ryhl wrote: > These are the functions needed by Binder's shrinker. > > Binder uses zap_page_range_single in the shrinker path to remove an > unused page from the mmap'd region. Note that pages are only removed > from the mmap'd region lazily when shrinker asks for it. > > Binder uses list_lru_add/del to keep track of the shrinker lru list, and > it can't use _obj because the list head is not stored inline in the page > actually being lru freed, so page_to_nid(virt_to_page(item)) on the list > head computes the nid of the wrong page. > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > --- > mm/list_lru.c | 2 ++ > mm/memory.c | 1 + > 2 files changed, 3 insertions(+) > > diff --git a/mm/list_lru.c b/mm/list_lru.c > index ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644 > --- a/mm/list_lru.c > +++ b/mm/list_lru.c > @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, > unlock_list_lru(l, false); > return false; > } > +EXPORT_SYMBOL_GPL(list_lru_add); > > bool list_lru_add_obj(struct list_lru *lru, struct list_head *item) > { > @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, > unlock_list_lru(l, false); > return false; > } > +EXPORT_SYMBOL_GPL(list_lru_del); > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) > { > diff --git a/mm/memory.c b/mm/memory.c > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > zap_page_range_single_batched(&tlb, vma, address, size, details); > tlb_finish_mmu(&tlb); > } > +EXPORT_SYMBOL(zap_page_range_single); Why not EXPORT_SYMBOL_GPL? -- Cheers, David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 10:59 ` David Hildenbrand (arm) @ 2026-02-05 11:04 ` Alice Ryhl 2026-02-05 11:12 ` David Hildenbrand (arm) 0 siblings, 1 reply; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 11:04 UTC (permalink / raw) To: David Hildenbrand (arm) Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 11:59:47AM +0100, David Hildenbrand (arm) wrote: > On 2/5/26 11:51, Alice Ryhl wrote: > > These are the functions needed by Binder's shrinker. > > > > Binder uses zap_page_range_single in the shrinker path to remove an > > unused page from the mmap'd region. Note that pages are only removed > > from the mmap'd region lazily when shrinker asks for it. > > > > Binder uses list_lru_add/del to keep track of the shrinker lru list, and > > it can't use _obj because the list head is not stored inline in the page > > actually being lru freed, so page_to_nid(virt_to_page(item)) on the list > > head computes the nid of the wrong page. > > > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > --- > > mm/list_lru.c | 2 ++ > > mm/memory.c | 1 + > > 2 files changed, 3 insertions(+) > > > > diff --git a/mm/list_lru.c b/mm/list_lru.c > > index ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644 > > --- a/mm/list_lru.c > > +++ b/mm/list_lru.c > > @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, > > unlock_list_lru(l, false); > > return false; > > } > > +EXPORT_SYMBOL_GPL(list_lru_add); > > bool list_lru_add_obj(struct list_lru *lru, struct list_head *item) > > { > > @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, > > unlock_list_lru(l, false); > > return false; > > } > > +EXPORT_SYMBOL_GPL(list_lru_del); > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) > > { > > diff --git a/mm/memory.c b/mm/memory.c > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 > > --- a/mm/memory.c > > +++ b/mm/memory.c > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > > zap_page_range_single_batched(&tlb, vma, address, size, details); > > tlb_finish_mmu(&tlb); > > } > > +EXPORT_SYMBOL(zap_page_range_single); > > Why not EXPORT_SYMBOL_GPL? I just tried to match other symbols in the same file. Alice ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:04 ` Alice Ryhl @ 2026-02-05 11:12 ` David Hildenbrand (arm) 2026-02-05 11:18 ` Alice Ryhl 0 siblings, 1 reply; 43+ messages in thread From: David Hildenbrand (arm) @ 2026-02-05 11:12 UTC (permalink / raw) To: Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On 2/5/26 12:04, Alice Ryhl wrote: > On Thu, Feb 05, 2026 at 11:59:47AM +0100, David Hildenbrand (arm) wrote: >> On 2/5/26 11:51, Alice Ryhl wrote: >>> These are the functions needed by Binder's shrinker. >>> >>> Binder uses zap_page_range_single in the shrinker path to remove an >>> unused page from the mmap'd region. Note that pages are only removed >>> from the mmap'd region lazily when shrinker asks for it. >>> >>> Binder uses list_lru_add/del to keep track of the shrinker lru list, and >>> it can't use _obj because the list head is not stored inline in the page >>> actually being lru freed, so page_to_nid(virt_to_page(item)) on the list >>> head computes the nid of the wrong page. >>> >>> Signed-off-by: Alice Ryhl <aliceryhl@google.com> >>> --- >>> mm/list_lru.c | 2 ++ >>> mm/memory.c | 1 + >>> 2 files changed, 3 insertions(+) >>> >>> diff --git a/mm/list_lru.c b/mm/list_lru.c >>> index ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644 >>> --- a/mm/list_lru.c >>> +++ b/mm/list_lru.c >>> @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, >>> unlock_list_lru(l, false); >>> return false; >>> } >>> +EXPORT_SYMBOL_GPL(list_lru_add); >>> bool list_lru_add_obj(struct list_lru *lru, struct list_head *item) >>> { >>> @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, >>> unlock_list_lru(l, false); >>> return false; >>> } >>> +EXPORT_SYMBOL_GPL(list_lru_del); >>> bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) >>> { >>> diff --git a/mm/memory.c b/mm/memory.c >>> index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 >>> --- a/mm/memory.c >>> +++ b/mm/memory.c >>> @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, >>> zap_page_range_single_batched(&tlb, vma, address, size, details); >>> tlb_finish_mmu(&tlb); >>> } >>> +EXPORT_SYMBOL(zap_page_range_single); >> >> Why not EXPORT_SYMBOL_GPL? > > I just tried to match other symbols in the same file. We were probably a bit too sloppy with some of these in the past. But: davhil01@e142025:~/git/linux$ grep -c "EXPORT_SYMBOL(" mm/memory.c 12 davhil01@e142025:~/git/linux$ grep -c "EXPORT_SYMBOL_GPL(" mm/memory.c 10 So just go with EXPORT_SYMBOL_GPL unless there is a good reason why not. -- Cheers, David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:12 ` David Hildenbrand (arm) @ 2026-02-05 11:18 ` Alice Ryhl 2026-02-05 11:30 ` David Hildenbrand (arm) 0 siblings, 1 reply; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 11:18 UTC (permalink / raw) To: David Hildenbrand (arm) Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 12:12:23PM +0100, David Hildenbrand (arm) wrote: > On 2/5/26 12:04, Alice Ryhl wrote: > > On Thu, Feb 05, 2026 at 11:59:47AM +0100, David Hildenbrand (arm) wrote: > > > On 2/5/26 11:51, Alice Ryhl wrote: > > > > diff --git a/mm/list_lru.c b/mm/list_lru.c > > > > index ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644 > > > > --- a/mm/list_lru.c > > > > +++ b/mm/list_lru.c > > > > @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, > > > > unlock_list_lru(l, false); > > > > return false; > > > > } > > > > +EXPORT_SYMBOL_GPL(list_lru_add); > > > > bool list_lru_add_obj(struct list_lru *lru, struct list_head *item) > > > > { > > > > @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, > > > > unlock_list_lru(l, false); > > > > return false; > > > > } > > > > +EXPORT_SYMBOL_GPL(list_lru_del); > > > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) > > > > { > > > > diff --git a/mm/memory.c b/mm/memory.c > > > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 > > > > --- a/mm/memory.c > > > > +++ b/mm/memory.c > > > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > > > > zap_page_range_single_batched(&tlb, vma, address, size, details); > > > > tlb_finish_mmu(&tlb); > > > > } > > > > +EXPORT_SYMBOL(zap_page_range_single); > > > > > > Why not EXPORT_SYMBOL_GPL? > > > > I just tried to match other symbols in the same file. > > We were probably a bit too sloppy with some of these in the past. But: > > davhil01@e142025:~/git/linux$ grep -c "EXPORT_SYMBOL(" mm/memory.c > 12 > davhil01@e142025:~/git/linux$ grep -c "EXPORT_SYMBOL_GPL(" mm/memory.c > 10 > > So just go with EXPORT_SYMBOL_GPL unless there is a good reason why not. Sounds good, I'll do that in the next version. Alice ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:18 ` Alice Ryhl @ 2026-02-05 11:30 ` David Hildenbrand (arm) 0 siblings, 0 replies; 43+ messages in thread From: David Hildenbrand (arm) @ 2026-02-05 11:30 UTC (permalink / raw) To: Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On 2/5/26 12:18, Alice Ryhl wrote: > On Thu, Feb 05, 2026 at 12:12:23PM +0100, David Hildenbrand (arm) wrote: >> On 2/5/26 12:04, Alice Ryhl wrote: >>> >>> I just tried to match other symbols in the same file. >> >> We were probably a bit too sloppy with some of these in the past. But: >> >> davhil01@e142025:~/git/linux$ grep -c "EXPORT_SYMBOL(" mm/memory.c >> 12 >> davhil01@e142025:~/git/linux$ grep -c "EXPORT_SYMBOL_GPL(" mm/memory.c >> 10 >> >> So just go with EXPORT_SYMBOL_GPL unless there is a good reason why not. > > Sounds good, I'll do that in the next version. Feel free to add my Acked-by: David Hildenbrand (arm) <david@kernel.org> -- Cheers, David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 10:51 ` [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del Alice Ryhl 2026-02-05 10:59 ` David Hildenbrand (arm) @ 2026-02-05 11:29 ` Lorenzo Stoakes 2026-02-05 11:43 ` David Hildenbrand (arm) 2026-02-05 12:07 ` Alice Ryhl 1 sibling, 2 replies; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 11:29 UTC (permalink / raw) To: Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote: > These are the functions needed by Binder's shrinker. > > Binder uses zap_page_range_single in the shrinker path to remove an > unused page from the mmap'd region. Note that pages are only removed > from the mmap'd region lazily when shrinker asks for it. > > Binder uses list_lru_add/del to keep track of the shrinker lru list, and > it can't use _obj because the list head is not stored inline in the page > actually being lru freed, so page_to_nid(virt_to_page(item)) on the list > head computes the nid of the wrong page. > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > --- > mm/list_lru.c | 2 ++ > mm/memory.c | 1 + > 2 files changed, 3 insertions(+) > > diff --git a/mm/list_lru.c b/mm/list_lru.c > index ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644 > --- a/mm/list_lru.c > +++ b/mm/list_lru.c > @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, > unlock_list_lru(l, false); > return false; > } > +EXPORT_SYMBOL_GPL(list_lru_add); > > bool list_lru_add_obj(struct list_lru *lru, struct list_head *item) > { > @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, > unlock_list_lru(l, false); > return false; > } > +EXPORT_SYMBOL_GPL(list_lru_del); Same point as before about exporting symbols, but given the _obj variants are exported already this one is more valid. > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) > { > diff --git a/mm/memory.c b/mm/memory.c > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > zap_page_range_single_batched(&tlb, vma, address, size, details); > tlb_finish_mmu(&tlb); > } > +EXPORT_SYMBOL(zap_page_range_single); Sorry but I don't want this exported at all. This is an internal implementation detail which allows fine-grained control of behaviour via struct zap_details (which binder doesn't use, of course :) We either need a wrapper that eliminates this parameter (but then we're adding a wrapper to this behaviour that is literally for one driver that is _temporarily_ being modularised which is weak justifiction), or use of a function that invokes it that is currently exported. Again the general policy with exports is that we really don't want to provide them at all if we can help it, and if we do, only when it's really justified. Drivers by nature generally abuse any interfaces provided, we reduce the surface area of bugs in the kernel by minimising what's available (even via header for in-tree...) > > /** > * zap_vma_ptes - remove ptes mapping the vma > > -- > 2.53.0.rc2.204.g2597b5adb4-goog > Cheers, Lorenzo ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:29 ` Lorenzo Stoakes @ 2026-02-05 11:43 ` David Hildenbrand (arm) 2026-02-05 11:57 ` David Hildenbrand (arm) ` (2 more replies) 2026-02-05 12:07 ` Alice Ryhl 1 sibling, 3 replies; 43+ messages in thread From: David Hildenbrand (arm) @ 2026-02-05 11:43 UTC (permalink / raw) To: Lorenzo Stoakes, Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On 2/5/26 12:29, Lorenzo Stoakes wrote: > On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote: >> These are the functions needed by Binder's shrinker. >> >> Binder uses zap_page_range_single in the shrinker path to remove an >> unused page from the mmap'd region. Note that pages are only removed >> from the mmap'd region lazily when shrinker asks for it. >> >> Binder uses list_lru_add/del to keep track of the shrinker lru list, and >> it can't use _obj because the list head is not stored inline in the page >> actually being lru freed, so page_to_nid(virt_to_page(item)) on the list >> head computes the nid of the wrong page. >> >> Signed-off-by: Alice Ryhl <aliceryhl@google.com> >> --- >> mm/list_lru.c | 2 ++ >> mm/memory.c | 1 + >> 2 files changed, 3 insertions(+) >> >> diff --git a/mm/list_lru.c b/mm/list_lru.c >> index ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644 >> --- a/mm/list_lru.c >> +++ b/mm/list_lru.c >> @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, >> unlock_list_lru(l, false); >> return false; >> } >> +EXPORT_SYMBOL_GPL(list_lru_add); >> >> bool list_lru_add_obj(struct list_lru *lru, struct list_head *item) >> { >> @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, >> unlock_list_lru(l, false); >> return false; >> } >> +EXPORT_SYMBOL_GPL(list_lru_del); > > Same point as before about exporting symbols, but given the _obj variants are > exported already this one is more valid. > >> >> bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) >> { >> diff --git a/mm/memory.c b/mm/memory.c >> index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 >> --- a/mm/memory.c >> +++ b/mm/memory.c >> @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, >> zap_page_range_single_batched(&tlb, vma, address, size, details); >> tlb_finish_mmu(&tlb); >> } >> +EXPORT_SYMBOL(zap_page_range_single); > > Sorry but I don't want this exported at all. > > This is an internal implementation detail which allows fine-grained control of > behaviour via struct zap_details (which binder doesn't use, of course :) I don't expect anybody to set zap_details, but yeah, it could be abused. It could be abused right now from anywhere else in the kernel where we don't build as a module :) Apparently we export a similar function in rust where we just removed the last parameter. I think zap_page_range_single() is only called with non-NULL from mm/memory.c. So the following makes likely sense even outside of the context of this series: From d2a2d20994456b9a66008b7fef12e379e76fc9f8 Mon Sep 17 00:00:00 2001 From: "David Hildenbrand (arm)" <david@kernel.org> Date: Thu, 5 Feb 2026 12:42:09 +0100 Subject: [PATCH] tmp Signed-off-by: David Hildenbrand (arm) <david@kernel.org> --- arch/s390/mm/gmap_helpers.c | 2 +- drivers/android/binder_alloc.c | 2 +- include/linux/mm.h | 4 ++-- kernel/bpf/arena.c | 3 +-- kernel/events/core.c | 2 +- mm/memory.c | 15 +++++++++------ net/ipv4/tcp.c | 5 ++--- rust/kernel/mm/virt.rs | 2 +- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/arch/s390/mm/gmap_helpers.c b/arch/s390/mm/gmap_helpers.c index d41b19925a5a..859f5570c3dc 100644 --- a/arch/s390/mm/gmap_helpers.c +++ b/arch/s390/mm/gmap_helpers.c @@ -102,7 +102,7 @@ void gmap_helper_discard(struct mm_struct *mm, unsigned long vmaddr, unsigned lo if (!vma) return; if (!is_vm_hugetlb_page(vma)) - zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr, NULL); + zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr); vmaddr = vma->vm_end; } } diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 979c96b74cad..b0201bc6893a 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -1186,7 +1186,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, if (vma) { trace_binder_unmap_user_start(alloc, index); - zap_page_range_single(vma, page_addr, PAGE_SIZE, NULL); + zap_page_range_single(vma, page_addr, PAGE_SIZE); trace_binder_unmap_user_end(alloc, index); } diff --git a/include/linux/mm.h b/include/linux/mm.h index f0d5be9dc736..b7cc6ef49917 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2621,11 +2621,11 @@ struct page *vm_normal_page_pud(struct vm_area_struct *vma, unsigned long addr, void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, unsigned long size); void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, - unsigned long size, struct zap_details *details); + unsigned long size); static inline void zap_vma_pages(struct vm_area_struct *vma) { zap_page_range_single(vma, vma->vm_start, - vma->vm_end - vma->vm_start, NULL); + vma->vm_end - vma->vm_start); } void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas, struct vm_area_struct *start_vma, unsigned long start, diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c index 872dc0e41c65..242c931d3740 100644 --- a/kernel/bpf/arena.c +++ b/kernel/bpf/arena.c @@ -503,8 +503,7 @@ static void zap_pages(struct bpf_arena *arena, long uaddr, long page_cnt) struct vma_list *vml; list_for_each_entry(vml, &arena->vma_list, head) - zap_page_range_single(vml->vma, uaddr, - PAGE_SIZE * page_cnt, NULL); + zap_page_range_single(vml->vma, uaddr, PAGE_SIZE * page_cnt); } static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt) diff --git a/kernel/events/core.c b/kernel/events/core.c index 8cca80094624..1dfb33c39c2f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6926,7 +6926,7 @@ static int map_range(struct perf_buffer *rb, struct vm_area_struct *vma) #ifdef CONFIG_MMU /* Clear any partial mappings on error. */ if (err) - zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE, NULL); + zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE); #endif return err; diff --git a/mm/memory.c b/mm/memory.c index da360a6eb8a4..4f8dcdcd20f3 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2155,17 +2155,16 @@ void zap_page_range_single_batched(struct mmu_gather *tlb, * @vma: vm_area_struct holding the applicable pages * @address: starting address of pages to zap * @size: number of bytes to zap - * @details: details of shared cache invalidation * * The range must fit into one VMA. */ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, - unsigned long size, struct zap_details *details) + unsigned long size) { struct mmu_gather tlb; tlb_gather_mmu(&tlb, vma->vm_mm); - zap_page_range_single_batched(&tlb, vma, address, size, details); + zap_page_range_single_batched(&tlb, vma, address, size, NULL); tlb_finish_mmu(&tlb); } @@ -2187,7 +2186,7 @@ void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, !(vma->vm_flags & VM_PFNMAP)) return; - zap_page_range_single(vma, address, size, NULL); + zap_page_range_single(vma, address, size); } EXPORT_SYMBOL_GPL(zap_vma_ptes); @@ -2963,7 +2962,7 @@ static int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long add * maintain page reference counts, and callers may free * pages due to the error. So zap it early. */ - zap_page_range_single(vma, addr, size, NULL); + zap_page_range_single(vma, addr, size); return error; } @@ -4187,7 +4186,11 @@ static void unmap_mapping_range_vma(struct vm_area_struct *vma, unsigned long start_addr, unsigned long end_addr, struct zap_details *details) { - zap_page_range_single(vma, start_addr, end_addr - start_addr, details); + struct mmu_gather tlb; + + tlb_gather_mmu(&tlb, vma->vm_mm); + zap_page_range_single_batched(&tlb, vma, address, size, details); + tlb_finish_mmu(&tlb); } static inline void unmap_mapping_range_tree(struct rb_root_cached *root, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index d5319ebe2452..9e92c71389f3 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2052,7 +2052,7 @@ static int tcp_zerocopy_vm_insert_batch_error(struct vm_area_struct *vma, maybe_zap_len = total_bytes_to_map - /* All bytes to map */ *length + /* Mapped or pending */ (pages_remaining * PAGE_SIZE); /* Failed map. */ - zap_page_range_single(vma, *address, maybe_zap_len, NULL); + zap_page_range_single(vma, *address, maybe_zap_len); err = 0; } @@ -2217,8 +2217,7 @@ static int tcp_zerocopy_receive(struct sock *sk, total_bytes_to_map = avail_len & ~(PAGE_SIZE - 1); if (total_bytes_to_map) { if (!(zc->flags & TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT)) - zap_page_range_single(vma, address, total_bytes_to_map, - NULL); + zap_page_range_single(vma, address, total_bytes_to_map); zc->length = total_bytes_to_map; zc->recv_skip_hint = 0; } else { diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs index da21d65ccd20..b8e59e4420f3 100644 --- a/rust/kernel/mm/virt.rs +++ b/rust/kernel/mm/virt.rs @@ -124,7 +124,7 @@ pub fn zap_page_range_single(&self, address: usize, size: usize) { // sufficient for this method call. This method has no requirements on the vma flags. The // address range is checked to be within the vma. unsafe { - bindings::zap_page_range_single(self.as_ptr(), address, size, core::ptr::null_mut()) + bindings::zap_page_range_single(self.as_ptr(), address, size) }; } -- 2.43.0 -- Cheers, David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:43 ` David Hildenbrand (arm) @ 2026-02-05 11:57 ` David Hildenbrand (arm) 2026-02-05 12:01 ` Lorenzo Stoakes 2026-02-05 11:57 ` Lorenzo Stoakes 2026-02-05 11:58 ` Alice Ryhl 2 siblings, 1 reply; 43+ messages in thread From: David Hildenbrand (arm) @ 2026-02-05 11:57 UTC (permalink / raw) To: Lorenzo Stoakes, Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On 2/5/26 12:43, David Hildenbrand (arm) wrote: > On 2/5/26 12:29, Lorenzo Stoakes wrote: >> On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote: >>> These are the functions needed by Binder's shrinker. >>> >>> Binder uses zap_page_range_single in the shrinker path to remove an >>> unused page from the mmap'd region. Note that pages are only removed >>> from the mmap'd region lazily when shrinker asks for it. >>> >>> Binder uses list_lru_add/del to keep track of the shrinker lru list, and >>> it can't use _obj because the list head is not stored inline in the page >>> actually being lru freed, so page_to_nid(virt_to_page(item)) on the list >>> head computes the nid of the wrong page. >>> >>> Signed-off-by: Alice Ryhl <aliceryhl@google.com> >>> --- >>> mm/list_lru.c | 2 ++ >>> mm/memory.c | 1 + >>> 2 files changed, 3 insertions(+) >>> >>> diff --git a/mm/list_lru.c b/mm/list_lru.c >>> index >>> ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644 >>> --- a/mm/list_lru.c >>> +++ b/mm/list_lru.c >>> @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct >>> list_head *item, int nid, >>> unlock_list_lru(l, false); >>> return false; >>> } >>> +EXPORT_SYMBOL_GPL(list_lru_add); >>> >>> bool list_lru_add_obj(struct list_lru *lru, struct list_head *item) >>> { >>> @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct >>> list_head *item, int nid, >>> unlock_list_lru(l, false); >>> return false; >>> } >>> +EXPORT_SYMBOL_GPL(list_lru_del); >> >> Same point as before about exporting symbols, but given the _obj >> variants are >> exported already this one is more valid. >> >>> >>> bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) >>> { >>> diff --git a/mm/memory.c b/mm/memory.c >>> index >>> da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 >>> --- a/mm/memory.c >>> +++ b/mm/memory.c >>> @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct >>> vm_area_struct *vma, unsigned long address, >>> zap_page_range_single_batched(&tlb, vma, address, size, details); >>> tlb_finish_mmu(&tlb); >>> } >>> +EXPORT_SYMBOL(zap_page_range_single); >> >> Sorry but I don't want this exported at all. >> >> This is an internal implementation detail which allows fine-grained >> control of >> behaviour via struct zap_details (which binder doesn't use, of course :) > > I don't expect anybody to set zap_details, but yeah, it could be abused. > It could be abused right now from anywhere else in the kernel > where we don't build as a module :) > > Apparently we export a similar function in rust where we just removed > the last parameter. > > I think zap_page_range_single() is only called with non-NULL from mm/ > memory.c. > > So the following makes likely sense even outside of the context of this > series: The following should compile :) From b1c35afb1b819a42f4ec1119564b3b37cceb9968 Mon Sep 17 00:00:00 2001 From: "David Hildenbrand (arm)" <david@kernel.org> Date: Thu, 5 Feb 2026 12:42:09 +0100 Subject: [PATCH] mm/memory: remove "zap_details" parameter from zap_page_range_single() Nobody except memory.c should really set that parameter to non-NULL. So let's just drop it and make unmap_mapping_range_vma() use zap_page_range_single_batched() instead. Signed-off-by: David Hildenbrand (arm) <david@kernel.org> --- arch/s390/mm/gmap_helpers.c | 2 +- drivers/android/binder_alloc.c | 2 +- include/linux/mm.h | 5 ++--- kernel/bpf/arena.c | 3 +-- kernel/events/core.c | 2 +- mm/madvise.c | 3 +-- mm/memory.c | 16 ++++++++++------ net/ipv4/tcp.c | 5 ++--- rust/kernel/mm/virt.rs | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/s390/mm/gmap_helpers.c b/arch/s390/mm/gmap_helpers.c index d41b19925a5a..859f5570c3dc 100644 --- a/arch/s390/mm/gmap_helpers.c +++ b/arch/s390/mm/gmap_helpers.c @@ -102,7 +102,7 @@ void gmap_helper_discard(struct mm_struct *mm, unsigned long vmaddr, unsigned lo if (!vma) return; if (!is_vm_hugetlb_page(vma)) - zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr, NULL); + zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr); vmaddr = vma->vm_end; } } diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 979c96b74cad..b0201bc6893a 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -1186,7 +1186,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, if (vma) { trace_binder_unmap_user_start(alloc, index); - zap_page_range_single(vma, page_addr, PAGE_SIZE, NULL); + zap_page_range_single(vma, page_addr, PAGE_SIZE); trace_binder_unmap_user_end(alloc, index); } diff --git a/include/linux/mm.h b/include/linux/mm.h index f0d5be9dc736..5764991546bb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2621,11 +2621,10 @@ struct page *vm_normal_page_pud(struct vm_area_struct *vma, unsigned long addr, void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, unsigned long size); void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, - unsigned long size, struct zap_details *details); + unsigned long size); static inline void zap_vma_pages(struct vm_area_struct *vma) { - zap_page_range_single(vma, vma->vm_start, - vma->vm_end - vma->vm_start, NULL); + zap_page_range_single(vma, vma->vm_start, vma->vm_end - vma->vm_start); } void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas, struct vm_area_struct *start_vma, unsigned long start, diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c index 872dc0e41c65..242c931d3740 100644 --- a/kernel/bpf/arena.c +++ b/kernel/bpf/arena.c @@ -503,8 +503,7 @@ static void zap_pages(struct bpf_arena *arena, long uaddr, long page_cnt) struct vma_list *vml; list_for_each_entry(vml, &arena->vma_list, head) - zap_page_range_single(vml->vma, uaddr, - PAGE_SIZE * page_cnt, NULL); + zap_page_range_single(vml->vma, uaddr, PAGE_SIZE * page_cnt); } static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt) diff --git a/kernel/events/core.c b/kernel/events/core.c index 8cca80094624..1dfb33c39c2f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6926,7 +6926,7 @@ static int map_range(struct perf_buffer *rb, struct vm_area_struct *vma) #ifdef CONFIG_MMU /* Clear any partial mappings on error. */ if (err) - zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE, NULL); + zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE); #endif return err; diff --git a/mm/madvise.c b/mm/madvise.c index b617b1be0f53..abcbfd1f0662 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -1200,8 +1200,7 @@ static long madvise_guard_install(struct madvise_behavior *madv_behavior) * OK some of the range have non-guard pages mapped, zap * them. This leaves existing guard pages in place. */ - zap_page_range_single(vma, range->start, - range->end - range->start, NULL); + zap_page_range_single(vma, range->start, range->end - range->start); } /* diff --git a/mm/memory.c b/mm/memory.c index da360a6eb8a4..82985da5f7e6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2155,17 +2155,16 @@ void zap_page_range_single_batched(struct mmu_gather *tlb, * @vma: vm_area_struct holding the applicable pages * @address: starting address of pages to zap * @size: number of bytes to zap - * @details: details of shared cache invalidation * * The range must fit into one VMA. */ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, - unsigned long size, struct zap_details *details) + unsigned long size) { struct mmu_gather tlb; tlb_gather_mmu(&tlb, vma->vm_mm); - zap_page_range_single_batched(&tlb, vma, address, size, details); + zap_page_range_single_batched(&tlb, vma, address, size, NULL); tlb_finish_mmu(&tlb); } @@ -2187,7 +2186,7 @@ void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, !(vma->vm_flags & VM_PFNMAP)) return; - zap_page_range_single(vma, address, size, NULL); + zap_page_range_single(vma, address, size); } EXPORT_SYMBOL_GPL(zap_vma_ptes); @@ -2963,7 +2962,7 @@ static int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long add * maintain page reference counts, and callers may free * pages due to the error. So zap it early. */ - zap_page_range_single(vma, addr, size, NULL); + zap_page_range_single(vma, addr, size); return error; } @@ -4187,7 +4186,12 @@ static void unmap_mapping_range_vma(struct vm_area_struct *vma, unsigned long start_addr, unsigned long end_addr, struct zap_details *details) { - zap_page_range_single(vma, start_addr, end_addr - start_addr, details); + struct mmu_gather tlb; + + tlb_gather_mmu(&tlb, vma->vm_mm); + zap_page_range_single_batched(&tlb, vma, start_addr, + end_addr - start_addr, details); + tlb_finish_mmu(&tlb); } static inline void unmap_mapping_range_tree(struct rb_root_cached *root, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index d5319ebe2452..9e92c71389f3 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2052,7 +2052,7 @@ static int tcp_zerocopy_vm_insert_batch_error(struct vm_area_struct *vma, maybe_zap_len = total_bytes_to_map - /* All bytes to map */ *length + /* Mapped or pending */ (pages_remaining * PAGE_SIZE); /* Failed map. */ - zap_page_range_single(vma, *address, maybe_zap_len, NULL); + zap_page_range_single(vma, *address, maybe_zap_len); err = 0; } @@ -2217,8 +2217,7 @@ static int tcp_zerocopy_receive(struct sock *sk, total_bytes_to_map = avail_len & ~(PAGE_SIZE - 1); if (total_bytes_to_map) { if (!(zc->flags & TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT)) - zap_page_range_single(vma, address, total_bytes_to_map, - NULL); + zap_page_range_single(vma, address, total_bytes_to_map); zc->length = total_bytes_to_map; zc->recv_skip_hint = 0; } else { diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs index da21d65ccd20..b8e59e4420f3 100644 --- a/rust/kernel/mm/virt.rs +++ b/rust/kernel/mm/virt.rs @@ -124,7 +124,7 @@ pub fn zap_page_range_single(&self, address: usize, size: usize) { // sufficient for this method call. This method has no requirements on the vma flags. The // address range is checked to be within the vma. unsafe { - bindings::zap_page_range_single(self.as_ptr(), address, size, core::ptr::null_mut()) + bindings::zap_page_range_single(self.as_ptr(), address, size) }; } -- 2.43.0 -- Cheers, David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:57 ` David Hildenbrand (arm) @ 2026-02-05 12:01 ` Lorenzo Stoakes 2026-02-05 12:06 ` David Hildenbrand (arm) 0 siblings, 1 reply; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 12:01 UTC (permalink / raw) To: David Hildenbrand (arm) Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 12:57:04PM +0100, David Hildenbrand (arm) wrote: Dude you have to capitalise that 'a' in Arm it's driving me crazy ;) Then again should it be ARM? OK this is tricky [snip] > > The following should compile :) Err... yeah. OK my R-b obviously depends on the code being compiling + working :P But still feel free to add when you break it out + _test_ it ;) Cheers, Lorenzo > > From b1c35afb1b819a42f4ec1119564b3b37cceb9968 Mon Sep 17 00:00:00 2001 > From: "David Hildenbrand (arm)" <david@kernel.org> > Date: Thu, 5 Feb 2026 12:42:09 +0100 > Subject: [PATCH] mm/memory: remove "zap_details" parameter from > zap_page_range_single() > > Nobody except memory.c should really set that parameter to non-NULL. So > let's just drop it and make unmap_mapping_range_vma() use > zap_page_range_single_batched() instead. > > Signed-off-by: David Hildenbrand (arm) <david@kernel.org> > --- > arch/s390/mm/gmap_helpers.c | 2 +- > drivers/android/binder_alloc.c | 2 +- > include/linux/mm.h | 5 ++--- > kernel/bpf/arena.c | 3 +-- > kernel/events/core.c | 2 +- > mm/madvise.c | 3 +-- > mm/memory.c | 16 ++++++++++------ > net/ipv4/tcp.c | 5 ++--- > rust/kernel/mm/virt.rs | 2 +- > 9 files changed, 20 insertions(+), 20 deletions(-) > > diff --git a/arch/s390/mm/gmap_helpers.c b/arch/s390/mm/gmap_helpers.c > index d41b19925a5a..859f5570c3dc 100644 > --- a/arch/s390/mm/gmap_helpers.c > +++ b/arch/s390/mm/gmap_helpers.c > @@ -102,7 +102,7 @@ void gmap_helper_discard(struct mm_struct *mm, unsigned long vmaddr, unsigned lo > if (!vma) > return; > if (!is_vm_hugetlb_page(vma)) > - zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr, NULL); > + zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr); > vmaddr = vma->vm_end; > } > } > diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c > index 979c96b74cad..b0201bc6893a 100644 > --- a/drivers/android/binder_alloc.c > +++ b/drivers/android/binder_alloc.c > @@ -1186,7 +1186,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, > if (vma) { > trace_binder_unmap_user_start(alloc, index); > - zap_page_range_single(vma, page_addr, PAGE_SIZE, NULL); > + zap_page_range_single(vma, page_addr, PAGE_SIZE); > trace_binder_unmap_user_end(alloc, index); > } > diff --git a/include/linux/mm.h b/include/linux/mm.h > index f0d5be9dc736..5764991546bb 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -2621,11 +2621,10 @@ struct page *vm_normal_page_pud(struct vm_area_struct *vma, unsigned long addr, > void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, > unsigned long size); > void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > - unsigned long size, struct zap_details *details); > + unsigned long size); > static inline void zap_vma_pages(struct vm_area_struct *vma) > { > - zap_page_range_single(vma, vma->vm_start, > - vma->vm_end - vma->vm_start, NULL); > + zap_page_range_single(vma, vma->vm_start, vma->vm_end - vma->vm_start); > } > void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas, > struct vm_area_struct *start_vma, unsigned long start, > diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c > index 872dc0e41c65..242c931d3740 100644 > --- a/kernel/bpf/arena.c > +++ b/kernel/bpf/arena.c > @@ -503,8 +503,7 @@ static void zap_pages(struct bpf_arena *arena, long uaddr, long page_cnt) > struct vma_list *vml; > list_for_each_entry(vml, &arena->vma_list, head) > - zap_page_range_single(vml->vma, uaddr, > - PAGE_SIZE * page_cnt, NULL); > + zap_page_range_single(vml->vma, uaddr, PAGE_SIZE * page_cnt); > } > static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt) > diff --git a/kernel/events/core.c b/kernel/events/core.c > index 8cca80094624..1dfb33c39c2f 100644 > --- a/kernel/events/core.c > +++ b/kernel/events/core.c > @@ -6926,7 +6926,7 @@ static int map_range(struct perf_buffer *rb, struct vm_area_struct *vma) > #ifdef CONFIG_MMU > /* Clear any partial mappings on error. */ > if (err) > - zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE, NULL); > + zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE); > #endif > return err; > diff --git a/mm/madvise.c b/mm/madvise.c > index b617b1be0f53..abcbfd1f0662 100644 > --- a/mm/madvise.c > +++ b/mm/madvise.c > @@ -1200,8 +1200,7 @@ static long madvise_guard_install(struct madvise_behavior *madv_behavior) > * OK some of the range have non-guard pages mapped, zap > * them. This leaves existing guard pages in place. > */ > - zap_page_range_single(vma, range->start, > - range->end - range->start, NULL); > + zap_page_range_single(vma, range->start, range->end - range->start); > } > /* > diff --git a/mm/memory.c b/mm/memory.c > index da360a6eb8a4..82985da5f7e6 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -2155,17 +2155,16 @@ void zap_page_range_single_batched(struct mmu_gather *tlb, > * @vma: vm_area_struct holding the applicable pages > * @address: starting address of pages to zap > * @size: number of bytes to zap > - * @details: details of shared cache invalidation > * > * The range must fit into one VMA. > */ > void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > - unsigned long size, struct zap_details *details) > + unsigned long size) > { > struct mmu_gather tlb; > tlb_gather_mmu(&tlb, vma->vm_mm); > - zap_page_range_single_batched(&tlb, vma, address, size, details); > + zap_page_range_single_batched(&tlb, vma, address, size, NULL); > tlb_finish_mmu(&tlb); > } > @@ -2187,7 +2186,7 @@ void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, > !(vma->vm_flags & VM_PFNMAP)) > return; > - zap_page_range_single(vma, address, size, NULL); > + zap_page_range_single(vma, address, size); > } > EXPORT_SYMBOL_GPL(zap_vma_ptes); > @@ -2963,7 +2962,7 @@ static int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long add > * maintain page reference counts, and callers may free > * pages due to the error. So zap it early. > */ > - zap_page_range_single(vma, addr, size, NULL); > + zap_page_range_single(vma, addr, size); > return error; > } > @@ -4187,7 +4186,12 @@ static void unmap_mapping_range_vma(struct vm_area_struct *vma, > unsigned long start_addr, unsigned long end_addr, > struct zap_details *details) > { > - zap_page_range_single(vma, start_addr, end_addr - start_addr, details); > + struct mmu_gather tlb; > + > + tlb_gather_mmu(&tlb, vma->vm_mm); > + zap_page_range_single_batched(&tlb, vma, start_addr, > + end_addr - start_addr, details); > + tlb_finish_mmu(&tlb); > } > static inline void unmap_mapping_range_tree(struct rb_root_cached *root, > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c > index d5319ebe2452..9e92c71389f3 100644 > --- a/net/ipv4/tcp.c > +++ b/net/ipv4/tcp.c > @@ -2052,7 +2052,7 @@ static int tcp_zerocopy_vm_insert_batch_error(struct vm_area_struct *vma, > maybe_zap_len = total_bytes_to_map - /* All bytes to map */ > *length + /* Mapped or pending */ > (pages_remaining * PAGE_SIZE); /* Failed map. */ > - zap_page_range_single(vma, *address, maybe_zap_len, NULL); > + zap_page_range_single(vma, *address, maybe_zap_len); > err = 0; > } > @@ -2217,8 +2217,7 @@ static int tcp_zerocopy_receive(struct sock *sk, > total_bytes_to_map = avail_len & ~(PAGE_SIZE - 1); > if (total_bytes_to_map) { > if (!(zc->flags & TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT)) > - zap_page_range_single(vma, address, total_bytes_to_map, > - NULL); > + zap_page_range_single(vma, address, total_bytes_to_map); > zc->length = total_bytes_to_map; > zc->recv_skip_hint = 0; > } else { > diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs > index da21d65ccd20..b8e59e4420f3 100644 > --- a/rust/kernel/mm/virt.rs > +++ b/rust/kernel/mm/virt.rs > @@ -124,7 +124,7 @@ pub fn zap_page_range_single(&self, address: usize, size: usize) { > // sufficient for this method call. This method has no requirements on the vma flags. The > // address range is checked to be within the vma. > unsafe { > - bindings::zap_page_range_single(self.as_ptr(), address, size, core::ptr::null_mut()) > + bindings::zap_page_range_single(self.as_ptr(), address, size) > }; > } > -- > 2.43.0 > > > -- > Cheers, > > David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:01 ` Lorenzo Stoakes @ 2026-02-05 12:06 ` David Hildenbrand (arm) 2026-02-05 12:07 ` Lorenzo Stoakes 0 siblings, 1 reply; 43+ messages in thread From: David Hildenbrand (arm) @ 2026-02-05 12:06 UTC (permalink / raw) To: Lorenzo Stoakes Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On 2/5/26 13:01, Lorenzo Stoakes wrote: > On Thu, Feb 05, 2026 at 12:57:04PM +0100, David Hildenbrand (arm) wrote: > > Dude you have to capitalise that 'a' in Arm it's driving me crazy ;) > > Then again should it be ARM? OK this is tricky Yeah, I should likely adjust that at some point. For the time being, I enjoy driving you crazy :P > > [snip] > >> >> The following should compile :) > > Err... yeah. OK my R-b obviously depends on the code being compiling + working > :P But still feel free to add when you break it out + _test_ it ;) Better to add your R-b when I send it out officially :) -- Cheers, David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:06 ` David Hildenbrand (arm) @ 2026-02-05 12:07 ` Lorenzo Stoakes 0 siblings, 0 replies; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 12:07 UTC (permalink / raw) To: David Hildenbrand (arm) Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 01:06:10PM +0100, David Hildenbrand (arm) wrote: > On 2/5/26 13:01, Lorenzo Stoakes wrote: > > On Thu, Feb 05, 2026 at 12:57:04PM +0100, David Hildenbrand (arm) wrote: > > > > Dude you have to capitalise that 'a' in Arm it's driving me crazy ;) > > > > Then again should it be ARM? OK this is tricky > > Yeah, I should likely adjust that at some point. For the time being, I enjoy > driving you crazy :P :D > > > > > [snip] > > > > > > > > The following should compile :) > > > > Err... yeah. OK my R-b obviously depends on the code being compiling + working > > :P But still feel free to add when you break it out + _test_ it ;) > > Better to add your R-b when I send it out officially :) Haha yeah maybe... > > -- > Cheers, > > David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:43 ` David Hildenbrand (arm) 2026-02-05 11:57 ` David Hildenbrand (arm) @ 2026-02-05 11:57 ` Lorenzo Stoakes 2026-02-05 12:03 ` David Hildenbrand (arm) 2026-02-05 12:24 ` Miguel Ojeda 2026-02-05 11:58 ` Alice Ryhl 2 siblings, 2 replies; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 11:57 UTC (permalink / raw) To: David Hildenbrand (arm) Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Christoph Hellwig +cc Christoph for his input on exports here. On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote: > On 2/5/26 12:29, Lorenzo Stoakes wrote: > > On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote: > > > These are the functions needed by Binder's shrinker. > > > > > > Binder uses zap_page_range_single in the shrinker path to remove an > > > unused page from the mmap'd region. Note that pages are only removed > > > from the mmap'd region lazily when shrinker asks for it. > > > > > > Binder uses list_lru_add/del to keep track of the shrinker lru list, and > > > it can't use _obj because the list head is not stored inline in the page > > > actually being lru freed, so page_to_nid(virt_to_page(item)) on the list > > > head computes the nid of the wrong page. > > > > > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > > --- > > > mm/list_lru.c | 2 ++ > > > mm/memory.c | 1 + > > > 2 files changed, 3 insertions(+) > > > > > > diff --git a/mm/list_lru.c b/mm/list_lru.c > > > index ec48b5dadf519a5296ac14cda035c067f9e448f8..bf95d73c9815548a19db6345f856cee9baad22e3 100644 > > > --- a/mm/list_lru.c > > > +++ b/mm/list_lru.c > > > @@ -179,6 +179,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, > > > unlock_list_lru(l, false); > > > return false; > > > } > > > +EXPORT_SYMBOL_GPL(list_lru_add); > > > > > > bool list_lru_add_obj(struct list_lru *lru, struct list_head *item) > > > { > > > @@ -216,6 +217,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, > > > unlock_list_lru(l, false); > > > return false; > > > } > > > +EXPORT_SYMBOL_GPL(list_lru_del); > > > > Same point as before about exporting symbols, but given the _obj variants are > > exported already this one is more valid. > > > > > > > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) > > > { > > > diff --git a/mm/memory.c b/mm/memory.c > > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 > > > --- a/mm/memory.c > > > +++ b/mm/memory.c > > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > > > zap_page_range_single_batched(&tlb, vma, address, size, details); > > > tlb_finish_mmu(&tlb); > > > } > > > +EXPORT_SYMBOL(zap_page_range_single); > > > > Sorry but I don't want this exported at all. > > > > This is an internal implementation detail which allows fine-grained control of > > behaviour via struct zap_details (which binder doesn't use, of course :) > > I don't expect anybody to set zap_details, but yeah, it could be abused. > It could be abused right now from anywhere else in the kernel > where we don't build as a module :) > > Apparently we export a similar function in rust where we just removed the last parameter. What?? Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked EXPORT_SYMBOL*() for use by other rust modules? It's important we keep this in sync, otherwise rust is overriding kernel policy. > > I think zap_page_range_single() is only called with non-NULL from mm/memory.c. > > So the following makes likely sense even outside of the context of this series: > Yeah this looks good so feel free to add a R-b from me tag when you send it BUT... I'm still _very_ uncomfortable with exporting this just for binder which seems to be doing effectively mm tasks itself in a way that makes me think it needs a rework to not be doing that and to update core mm to add functionality if it's needed. In any case, if we _do_ export this I think I'm going to insist on this being EXPORT_SYMBOL_FOR_MODULES() _only_ for the binder in-tree module. Thanks, Lorenzo > From d2a2d20994456b9a66008b7fef12e379e76fc9f8 Mon Sep 17 00:00:00 2001 > From: "David Hildenbrand (arm)" <david@kernel.org> > Date: Thu, 5 Feb 2026 12:42:09 +0100 > Subject: [PATCH] tmp > > Signed-off-by: David Hildenbrand (arm) <david@kernel.org> > --- > arch/s390/mm/gmap_helpers.c | 2 +- > drivers/android/binder_alloc.c | 2 +- > include/linux/mm.h | 4 ++-- > kernel/bpf/arena.c | 3 +-- > kernel/events/core.c | 2 +- > mm/memory.c | 15 +++++++++------ > net/ipv4/tcp.c | 5 ++--- > rust/kernel/mm/virt.rs | 2 +- > 8 files changed, 18 insertions(+), 17 deletions(-) > > diff --git a/arch/s390/mm/gmap_helpers.c b/arch/s390/mm/gmap_helpers.c > index d41b19925a5a..859f5570c3dc 100644 > --- a/arch/s390/mm/gmap_helpers.c > +++ b/arch/s390/mm/gmap_helpers.c > @@ -102,7 +102,7 @@ void gmap_helper_discard(struct mm_struct *mm, unsigned long vmaddr, unsigned lo > if (!vma) > return; > if (!is_vm_hugetlb_page(vma)) > - zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr, NULL); > + zap_page_range_single(vma, vmaddr, min(end, vma->vm_end) - vmaddr); > vmaddr = vma->vm_end; > } > } > diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c > index 979c96b74cad..b0201bc6893a 100644 > --- a/drivers/android/binder_alloc.c > +++ b/drivers/android/binder_alloc.c > @@ -1186,7 +1186,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, > if (vma) { > trace_binder_unmap_user_start(alloc, index); > - zap_page_range_single(vma, page_addr, PAGE_SIZE, NULL); > + zap_page_range_single(vma, page_addr, PAGE_SIZE); > trace_binder_unmap_user_end(alloc, index); > } > diff --git a/include/linux/mm.h b/include/linux/mm.h > index f0d5be9dc736..b7cc6ef49917 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -2621,11 +2621,11 @@ struct page *vm_normal_page_pud(struct vm_area_struct *vma, unsigned long addr, > void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, > unsigned long size); > void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > - unsigned long size, struct zap_details *details); > + unsigned long size); > static inline void zap_vma_pages(struct vm_area_struct *vma) > { > zap_page_range_single(vma, vma->vm_start, > - vma->vm_end - vma->vm_start, NULL); > + vma->vm_end - vma->vm_start); > } > void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas, > struct vm_area_struct *start_vma, unsigned long start, > diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c > index 872dc0e41c65..242c931d3740 100644 > --- a/kernel/bpf/arena.c > +++ b/kernel/bpf/arena.c > @@ -503,8 +503,7 @@ static void zap_pages(struct bpf_arena *arena, long uaddr, long page_cnt) > struct vma_list *vml; > list_for_each_entry(vml, &arena->vma_list, head) > - zap_page_range_single(vml->vma, uaddr, > - PAGE_SIZE * page_cnt, NULL); > + zap_page_range_single(vml->vma, uaddr, PAGE_SIZE * page_cnt); > } > static void arena_free_pages(struct bpf_arena *arena, long uaddr, long page_cnt) > diff --git a/kernel/events/core.c b/kernel/events/core.c > index 8cca80094624..1dfb33c39c2f 100644 > --- a/kernel/events/core.c > +++ b/kernel/events/core.c > @@ -6926,7 +6926,7 @@ static int map_range(struct perf_buffer *rb, struct vm_area_struct *vma) > #ifdef CONFIG_MMU > /* Clear any partial mappings on error. */ > if (err) > - zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE, NULL); > + zap_page_range_single(vma, vma->vm_start, nr_pages * PAGE_SIZE); > #endif > return err; > diff --git a/mm/memory.c b/mm/memory.c > index da360a6eb8a4..4f8dcdcd20f3 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -2155,17 +2155,16 @@ void zap_page_range_single_batched(struct mmu_gather *tlb, > * @vma: vm_area_struct holding the applicable pages > * @address: starting address of pages to zap > * @size: number of bytes to zap > - * @details: details of shared cache invalidation > * > * The range must fit into one VMA. > */ > void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > - unsigned long size, struct zap_details *details) > + unsigned long size) > { > struct mmu_gather tlb; > tlb_gather_mmu(&tlb, vma->vm_mm); > - zap_page_range_single_batched(&tlb, vma, address, size, details); > + zap_page_range_single_batched(&tlb, vma, address, size, NULL); > tlb_finish_mmu(&tlb); > } > @@ -2187,7 +2186,7 @@ void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, > !(vma->vm_flags & VM_PFNMAP)) > return; > - zap_page_range_single(vma, address, size, NULL); > + zap_page_range_single(vma, address, size); > } > EXPORT_SYMBOL_GPL(zap_vma_ptes); > @@ -2963,7 +2962,7 @@ static int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long add > * maintain page reference counts, and callers may free > * pages due to the error. So zap it early. > */ > - zap_page_range_single(vma, addr, size, NULL); > + zap_page_range_single(vma, addr, size); > return error; > } > @@ -4187,7 +4186,11 @@ static void unmap_mapping_range_vma(struct vm_area_struct *vma, > unsigned long start_addr, unsigned long end_addr, > struct zap_details *details) > { > - zap_page_range_single(vma, start_addr, end_addr - start_addr, details); > + struct mmu_gather tlb; > + > + tlb_gather_mmu(&tlb, vma->vm_mm); > + zap_page_range_single_batched(&tlb, vma, address, size, details); > + tlb_finish_mmu(&tlb); > } > static inline void unmap_mapping_range_tree(struct rb_root_cached *root, > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c > index d5319ebe2452..9e92c71389f3 100644 > --- a/net/ipv4/tcp.c > +++ b/net/ipv4/tcp.c > @@ -2052,7 +2052,7 @@ static int tcp_zerocopy_vm_insert_batch_error(struct vm_area_struct *vma, > maybe_zap_len = total_bytes_to_map - /* All bytes to map */ > *length + /* Mapped or pending */ > (pages_remaining * PAGE_SIZE); /* Failed map. */ > - zap_page_range_single(vma, *address, maybe_zap_len, NULL); > + zap_page_range_single(vma, *address, maybe_zap_len); > err = 0; > } > @@ -2217,8 +2217,7 @@ static int tcp_zerocopy_receive(struct sock *sk, > total_bytes_to_map = avail_len & ~(PAGE_SIZE - 1); > if (total_bytes_to_map) { > if (!(zc->flags & TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT)) > - zap_page_range_single(vma, address, total_bytes_to_map, > - NULL); > + zap_page_range_single(vma, address, total_bytes_to_map); > zc->length = total_bytes_to_map; > zc->recv_skip_hint = 0; > } else { > diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs > index da21d65ccd20..b8e59e4420f3 100644 > --- a/rust/kernel/mm/virt.rs > +++ b/rust/kernel/mm/virt.rs > @@ -124,7 +124,7 @@ pub fn zap_page_range_single(&self, address: usize, size: usize) { > // sufficient for this method call. This method has no requirements on the vma flags. The > // address range is checked to be within the vma. > unsafe { > - bindings::zap_page_range_single(self.as_ptr(), address, size, core::ptr::null_mut()) > + bindings::zap_page_range_single(self.as_ptr(), address, size) > }; > } > -- > 2.43.0 > > > -- > Cheers, > > David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:57 ` Lorenzo Stoakes @ 2026-02-05 12:03 ` David Hildenbrand (arm) 2026-02-05 12:12 ` Lorenzo Stoakes 2026-02-05 12:24 ` Miguel Ojeda 1 sibling, 1 reply; 43+ messages in thread From: David Hildenbrand (arm) @ 2026-02-05 12:03 UTC (permalink / raw) To: Lorenzo Stoakes Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Christoph Hellwig On 2/5/26 12:57, Lorenzo Stoakes wrote: > +cc Christoph for his input on exports here. > > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote: >> On 2/5/26 12:29, Lorenzo Stoakes wrote: >>> >>> Same point as before about exporting symbols, but given the _obj variants are >>> exported already this one is more valid. >>> >>> >>> Sorry but I don't want this exported at all. >>> >>> This is an internal implementation detail which allows fine-grained control of >>> behaviour via struct zap_details (which binder doesn't use, of course :) >> >> I don't expect anybody to set zap_details, but yeah, it could be abused. >> It could be abused right now from anywhere else in the kernel >> where we don't build as a module :) >> >> Apparently we export a similar function in rust where we just removed the last parameter. > > What?? > > Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked > EXPORT_SYMBOL*() for use by other rust modules? > > It's important we keep this in sync, otherwise rust is overriding kernel policy. > >> >> I think zap_page_range_single() is only called with non-NULL from mm/memory.c. >> >> So the following makes likely sense even outside of the context of this series: >> > > Yeah this looks good so feel free to add a R-b from me tag when you send it > BUT... > > I'm still _very_ uncomfortable with exporting this just for binder which seems > to be doing effectively mm tasks itself in a way that makes me think it needs a > rework to not be doing that and to update core mm to add functionality if it's > needed. > > In any case, if we _do_ export this I think I'm going to insist on this being > EXPORT_SYMBOL_FOR_MODULES() _only_ for the binder in-tree module. Works for me. Staring at it again, I think I landed in cleanup land. zap_vma_ptes() is exported and does the same thing as zap_page_range_single(), just with some additional safety checks. Fun. Let me cleanup. Good finger exercise after one month of almost-not coding :) -- Cheers, David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:03 ` David Hildenbrand (arm) @ 2026-02-05 12:12 ` Lorenzo Stoakes 0 siblings, 0 replies; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 12:12 UTC (permalink / raw) To: David Hildenbrand (arm) Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Christoph Hellwig On Thu, Feb 05, 2026 at 01:03:35PM +0100, David Hildenbrand (arm) wrote: > On 2/5/26 12:57, Lorenzo Stoakes wrote: > > +cc Christoph for his input on exports here. > > > > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote: > > > On 2/5/26 12:29, Lorenzo Stoakes wrote: > > > > > > > > Same point as before about exporting symbols, but given the _obj variants are > > > > exported already this one is more valid. > > > > > > > > > > > > Sorry but I don't want this exported at all. > > > > > > > > This is an internal implementation detail which allows fine-grained control of > > > > behaviour via struct zap_details (which binder doesn't use, of course :) > > > > > > I don't expect anybody to set zap_details, but yeah, it could be abused. > > > It could be abused right now from anywhere else in the kernel > > > where we don't build as a module :) > > > > > > Apparently we export a similar function in rust where we just removed the last parameter. > > > > What?? > > > > Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked > > EXPORT_SYMBOL*() for use by other rust modules? > > > > It's important we keep this in sync, otherwise rust is overriding kernel policy. > > > > > > > > I think zap_page_range_single() is only called with non-NULL from mm/memory.c. > > > > > > So the following makes likely sense even outside of the context of this series: > > > > > > > Yeah this looks good so feel free to add a R-b from me tag when you send it > > BUT... > > > > I'm still _very_ uncomfortable with exporting this just for binder which seems > > to be doing effectively mm tasks itself in a way that makes me think it needs a > > rework to not be doing that and to update core mm to add functionality if it's > > needed. > > > > In any case, if we _do_ export this I think I'm going to insist on this being > > EXPORT_SYMBOL_FOR_MODULES() _only_ for the binder in-tree module. > > Works for me. :) > > Staring at it again, I think I landed in cleanup land. > > zap_vma_ptes() is exported and does the same thing as > zap_page_range_single(), just with some additional safety checks. Yeah saw that, except it insists only on VM_PFN VMAs which makes me question our making this more generally available to OOT drivers. > > Fun. > > > Let me cleanup. Good finger exercise after one month of almost-not coding :) :) I am less interested in cleanups at this stage at least for a while so feel free to fixup glaringly horrible things so I can vicariously enjoy it at least... > > -- > Cheers, > > David Cheers, Lorenzo ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:57 ` Lorenzo Stoakes 2026-02-05 12:03 ` David Hildenbrand (arm) @ 2026-02-05 12:24 ` Miguel Ojeda 2026-02-05 12:28 ` Lorenzo Stoakes 1 sibling, 1 reply; 43+ messages in thread From: Miguel Ojeda @ 2026-02-05 12:24 UTC (permalink / raw) To: Lorenzo Stoakes Cc: David Hildenbrand (arm), Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Christoph Hellwig On Thu, Feb 5, 2026 at 12:58 PM Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote: > > What?? > > Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked > EXPORT_SYMBOL*() for use by other rust modules? > > It's important we keep this in sync, otherwise rust is overriding kernel policy. Currently, Rust GPL-exports every mangled symbol from the `kernel` crate. To call something you would need to be a Rust caller (not C -- that is not supported at all, even if technically you could hack something up) and the Rust API would then need to give you access to it (i.e. you need to be able to pass the Rust language rules, e.g. being public etc.). In this case if we are talking about the `VmaRef` type, someone that can get a reference to a value of that type could then call the `zap_page_range_single` method. That in turns would try to call the C one, but that one is not exported, right? So it should be fine. In the future, for Rust, we may specify whether a particular crate exports or not (and perhaps even allow to export non-GPL, but originally it was decided to only export GPL stuff to be on the safe side; and perhaps in certain namespaces etc.). Cheers, Miguel ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:24 ` Miguel Ojeda @ 2026-02-05 12:28 ` Lorenzo Stoakes 0 siblings, 0 replies; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 12:28 UTC (permalink / raw) To: Miguel Ojeda Cc: David Hildenbrand (arm), Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Christoph Hellwig On Thu, Feb 05, 2026 at 01:24:09PM +0100, Miguel Ojeda wrote: > On Thu, Feb 5, 2026 at 12:58 PM Lorenzo Stoakes > <lorenzo.stoakes@oracle.com> wrote: > > > > What?? > > > > Alice - can you confirm rust isn't exporting stuff that isn't explicitly marked > > EXPORT_SYMBOL*() for use by other rust modules? > > > > It's important we keep this in sync, otherwise rust is overriding kernel policy. > > Currently, Rust GPL-exports every mangled symbol from the `kernel` > crate. To call something you would need to be a Rust caller (not C -- > that is not supported at all, even if technically you could hack > something up) and the Rust API would then need to give you access to > it (i.e. you need to be able to pass the Rust language rules, e.g. > being public etc.). > > In this case if we are talking about the `VmaRef` type, someone that > can get a reference to a value of that type could then call the > `zap_page_range_single` method. That in turns would try to call the C > one, but that one is not exported, right? So it should be fine. > OK cool. Thanks for the explanation. > In the future, for Rust, we may specify whether a particular crate > exports or not (and perhaps even allow to export non-GPL, but > originally it was decided to only export GPL stuff to be on the safe > side; and perhaps in certain namespaces etc.). We'd definitely need to keep this in sync with C exports, maybe we can find a nice way of doing/checking this. Generally we're _very_ conservative about exports, and actually it'd be nice if maybe rust only provided GPL ones. The GPL is a good thing :) But I guess we can figure that out later. > > Cheers, > Miguel Cheers, Lorenzo ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:43 ` David Hildenbrand (arm) 2026-02-05 11:57 ` David Hildenbrand (arm) 2026-02-05 11:57 ` Lorenzo Stoakes @ 2026-02-05 11:58 ` Alice Ryhl 2026-02-05 12:10 ` Lorenzo Stoakes 2 siblings, 1 reply; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 11:58 UTC (permalink / raw) To: David Hildenbrand (arm) Cc: Lorenzo Stoakes, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote: > On 2/5/26 12:29, Lorenzo Stoakes wrote: > > On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote: > > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) > > > { > > > diff --git a/mm/memory.c b/mm/memory.c > > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 > > > --- a/mm/memory.c > > > +++ b/mm/memory.c > > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > > > zap_page_range_single_batched(&tlb, vma, address, size, details); > > > tlb_finish_mmu(&tlb); > > > } > > > +EXPORT_SYMBOL(zap_page_range_single); > > > > Sorry but I don't want this exported at all. > > > > This is an internal implementation detail which allows fine-grained control of > > behaviour via struct zap_details (which binder doesn't use, of course :) > > I don't expect anybody to set zap_details, but yeah, it could be abused. > It could be abused right now from anywhere else in the kernel > where we don't build as a module :) > > Apparently we export a similar function in rust where we just removed the last parameter. To clarify, said Rust function gets inlined into Rust Binder, so Rust Binder calls the zap_page_range_single() symbol directly. Alice ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:58 ` Alice Ryhl @ 2026-02-05 12:10 ` Lorenzo Stoakes 2026-02-05 12:13 ` David Hildenbrand (arm) 2026-02-05 12:16 ` Alice Ryhl 0 siblings, 2 replies; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 12:10 UTC (permalink / raw) To: Alice Ryhl Cc: David Hildenbrand (arm), Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote: > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote: > > On 2/5/26 12:29, Lorenzo Stoakes wrote: > > > On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote: > > > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) > > > > { > > > > diff --git a/mm/memory.c b/mm/memory.c > > > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 > > > > --- a/mm/memory.c > > > > +++ b/mm/memory.c > > > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > > > > zap_page_range_single_batched(&tlb, vma, address, size, details); > > > > tlb_finish_mmu(&tlb); > > > > } > > > > +EXPORT_SYMBOL(zap_page_range_single); > > > > > > Sorry but I don't want this exported at all. > > > > > > This is an internal implementation detail which allows fine-grained control of > > > behaviour via struct zap_details (which binder doesn't use, of course :) > > > > I don't expect anybody to set zap_details, but yeah, it could be abused. > > It could be abused right now from anywhere else in the kernel > > where we don't build as a module :) > > > > Apparently we export a similar function in rust where we just removed the last parameter. > > To clarify, said Rust function gets inlined into Rust Binder, so Rust > Binder calls the zap_page_range_single() symbol directly. Presumably only for things compiled into the kernel right? ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:10 ` Lorenzo Stoakes @ 2026-02-05 12:13 ` David Hildenbrand (arm) 2026-02-05 12:19 ` Alice Ryhl 2026-02-05 12:16 ` Alice Ryhl 1 sibling, 1 reply; 43+ messages in thread From: David Hildenbrand (arm) @ 2026-02-05 12:13 UTC (permalink / raw) To: Lorenzo Stoakes, Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On 2/5/26 13:10, Lorenzo Stoakes wrote: > On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote: >> On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote: >>> >>> I don't expect anybody to set zap_details, but yeah, it could be abused. >>> It could be abused right now from anywhere else in the kernel >>> where we don't build as a module :) >>> >>> Apparently we export a similar function in rust where we just removed the last parameter. >> >> To clarify, said Rust function gets inlined into Rust Binder, so Rust >> Binder calls the zap_page_range_single() symbol directly. > > Presumably only for things compiled into the kernel right? Could Rust just use zap_vma_ptes() or does it want to zap things in VMAs that are not VM_PFNMAP? -- Cheers, David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:13 ` David Hildenbrand (arm) @ 2026-02-05 12:19 ` Alice Ryhl 2026-02-05 12:24 ` Lorenzo Stoakes 0 siblings, 1 reply; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 12:19 UTC (permalink / raw) To: David Hildenbrand (arm) Cc: Lorenzo Stoakes, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 01:13:57PM +0100, David Hildenbrand (arm) wrote: > On 2/5/26 13:10, Lorenzo Stoakes wrote: > > On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote: > > > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote: > > > > > > > > I don't expect anybody to set zap_details, but yeah, it could be abused. > > > > It could be abused right now from anywhere else in the kernel > > > > where we don't build as a module :) > > > > > > > > Apparently we export a similar function in rust where we just removed the last parameter. > > > > > > To clarify, said Rust function gets inlined into Rust Binder, so Rust > > > Binder calls the zap_page_range_single() symbol directly. > > > > Presumably only for things compiled into the kernel right? > > Could Rust just use zap_vma_ptes() or does it want to zap things in VMAs > that are not VM_PFNMAP? The VMA is VM_MIXEDMAP, not VM_PFNMAP. Alice ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:19 ` Alice Ryhl @ 2026-02-05 12:24 ` Lorenzo Stoakes 2026-02-05 12:30 ` David Hildenbrand (Arm) 0 siblings, 1 reply; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 12:24 UTC (permalink / raw) To: Alice Ryhl Cc: David Hildenbrand (arm), Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 12:19:22PM +0000, Alice Ryhl wrote: > On Thu, Feb 05, 2026 at 01:13:57PM +0100, David Hildenbrand (arm) wrote: > > On 2/5/26 13:10, Lorenzo Stoakes wrote: > > > On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote: > > > > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote: > > > > > > > > > > I don't expect anybody to set zap_details, but yeah, it could be abused. > > > > > It could be abused right now from anywhere else in the kernel > > > > > where we don't build as a module :) > > > > > > > > > > Apparently we export a similar function in rust where we just removed the last parameter. > > > > > > > > To clarify, said Rust function gets inlined into Rust Binder, so Rust > > > > Binder calls the zap_page_range_single() symbol directly. > > > > > > Presumably only for things compiled into the kernel right? > > > > Could Rust just use zap_vma_ptes() or does it want to zap things in VMAs > > that are not VM_PFNMAP? > > The VMA is VM_MIXEDMAP, not VM_PFNMAP. OK this smells like David's cleanup could extend it to allow for VM_MIXEDMAP :) then we solve the export problem. The two of these cause endless issues, it's really a mess... > > Alice Cheers, Lorenzo ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:24 ` Lorenzo Stoakes @ 2026-02-05 12:30 ` David Hildenbrand (Arm) 2026-02-09 15:22 ` Lorenzo Stoakes 0 siblings, 1 reply; 43+ messages in thread From: David Hildenbrand (Arm) @ 2026-02-05 12:30 UTC (permalink / raw) To: Lorenzo Stoakes, Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On 2/5/26 13:24, Lorenzo Stoakes wrote: > On Thu, Feb 05, 2026 at 12:19:22PM +0000, Alice Ryhl wrote: >> On Thu, Feb 05, 2026 at 01:13:57PM +0100, David Hildenbrand (arm) wrote: >>> >>> Could Rust just use zap_vma_ptes() or does it want to zap things in VMAs >>> that are not VM_PFNMAP? >> >> The VMA is VM_MIXEDMAP, not VM_PFNMAP. > > OK this smells like David's cleanup could extend it to allow for > VM_MIXEDMAP :) then we solve the export problem. My thinking ... and while at it, gonna remove these functions to make them a bit more ... consistent in naming. -- Cheers, David ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:30 ` David Hildenbrand (Arm) @ 2026-02-09 15:22 ` Lorenzo Stoakes 0 siblings, 0 replies; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-09 15:22 UTC (permalink / raw) To: David Hildenbrand (Arm) Cc: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 01:30:16PM +0100, David Hildenbrand (Arm) wrote: > On 2/5/26 13:24, Lorenzo Stoakes wrote: > > On Thu, Feb 05, 2026 at 12:19:22PM +0000, Alice Ryhl wrote: > > > On Thu, Feb 05, 2026 at 01:13:57PM +0100, David Hildenbrand (arm) wrote: > > > > > > > > Could Rust just use zap_vma_ptes() or does it want to zap things in VMAs > > > > that are not VM_PFNMAP? > > > > > > The VMA is VM_MIXEDMAP, not VM_PFNMAP. > > > > OK this smells like David's cleanup could extend it to allow for > > VM_MIXEDMAP :) then we solve the export problem. > > My thinking ... and while at it, gonna remove these functions to make them a > bit more ... consistent in naming. Sounds good :) > > -- > Cheers, > > David Cheers, Lorenzo ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:10 ` Lorenzo Stoakes 2026-02-05 12:13 ` David Hildenbrand (arm) @ 2026-02-05 12:16 ` Alice Ryhl 1 sibling, 0 replies; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 12:16 UTC (permalink / raw) To: Lorenzo Stoakes Cc: David Hildenbrand (arm), Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 12:10:38PM +0000, Lorenzo Stoakes wrote: > On Thu, Feb 05, 2026 at 11:58:00AM +0000, Alice Ryhl wrote: > > On Thu, Feb 05, 2026 at 12:43:03PM +0100, David Hildenbrand (arm) wrote: > > > On 2/5/26 12:29, Lorenzo Stoakes wrote: > > > > On Thu, Feb 05, 2026 at 10:51:28AM +0000, Alice Ryhl wrote: > > > > > bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) > > > > > { > > > > > diff --git a/mm/memory.c b/mm/memory.c > > > > > index da360a6eb8a48e29293430d0c577fb4b6ec58099..64083ace239a2caf58e1645dd5d91a41d61492c4 100644 > > > > > --- a/mm/memory.c > > > > > +++ b/mm/memory.c > > > > > @@ -2168,6 +2168,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address, > > > > > zap_page_range_single_batched(&tlb, vma, address, size, details); > > > > > tlb_finish_mmu(&tlb); > > > > > } > > > > > +EXPORT_SYMBOL(zap_page_range_single); > > > > > > > > Sorry but I don't want this exported at all. > > > > > > > > This is an internal implementation detail which allows fine-grained control of > > > > behaviour via struct zap_details (which binder doesn't use, of course :) > > > > > > I don't expect anybody to set zap_details, but yeah, it could be abused. > > > It could be abused right now from anywhere else in the kernel > > > where we don't build as a module :) > > > > > > Apparently we export a similar function in rust where we just removed the last parameter. > > > > To clarify, said Rust function gets inlined into Rust Binder, so Rust > > Binder calls the zap_page_range_single() symbol directly. > > Presumably only for things compiled into the kernel right? No, building Rust Binder with =m triggers this error for me: ERROR: modpost: "zap_page_range_single" [drivers/android/binder/rust_binder.ko] undefined! Alice ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 11:29 ` Lorenzo Stoakes 2026-02-05 11:43 ` David Hildenbrand (arm) @ 2026-02-05 12:07 ` Alice Ryhl 2026-02-05 12:18 ` Lorenzo Stoakes 1 sibling, 1 reply; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 12:07 UTC (permalink / raw) To: Lorenzo Stoakes Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 11:29:04AM +0000, Lorenzo Stoakes wrote: > We either need a wrapper that eliminates this parameter (but then we're adding a > wrapper to this behaviour that is literally for one driver that is _temporarily_ > being modularised which is weak justifiction), or use of a function that invokes > it that is currently exported. I have not talked with distros about it, but quite a few of them enable Binder because one or two applications want to use Binder to emulate Android. I imagine that even if Android itself goes back to built-in, distros would want it as a module so that you don't have to load it for every user, rather than for the few users that want to use waydroid or similar. A few examples: https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/blob/5711a17344ec7cfd90443374a30d5cd3e9a9439e/config#L10993 https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/config/arm64/config?ref_type=heads#L106 https://gitlab.com/cki-project/kernel-ark/-/blob/os-build/redhat/configs/fedora/generic/x86/CONFIG_ANDROID_BINDER_IPC?ref_type=heads Alice ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del 2026-02-05 12:07 ` Alice Ryhl @ 2026-02-05 12:18 ` Lorenzo Stoakes 0 siblings, 0 replies; 43+ messages in thread From: Lorenzo Stoakes @ 2026-02-05 12:18 UTC (permalink / raw) To: Alice Ryhl Cc: Greg Kroah-Hartman, Carlos Llamas, Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu, Feb 05, 2026 at 12:07:00PM +0000, Alice Ryhl wrote: > On Thu, Feb 05, 2026 at 11:29:04AM +0000, Lorenzo Stoakes wrote: > > We either need a wrapper that eliminates this parameter (but then we're adding a > > wrapper to this behaviour that is literally for one driver that is _temporarily_ > > being modularised which is weak justifiction), or use of a function that invokes > > it that is currently exported. > > I have not talked with distros about it, but quite a few of them enable > Binder because one or two applications want to use Binder to emulate > Android. I imagine that even if Android itself goes back to built-in, > distros would want it as a module so that you don't have to load it for > every user, rather than for the few users that want to use waydroid or > similar. > > A few examples: > https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/blob/5711a17344ec7cfd90443374a30d5cd3e9a9439e/config#L10993 > https://salsa.debian.org/kernel-team/linux/-/blob/debian/latest/debian/config/arm64/config?ref_type=heads#L106 > https://gitlab.com/cki-project/kernel-ark/-/blob/os-build/redhat/configs/fedora/generic/x86/CONFIG_ANDROID_BINDER_IPC?ref_type=heads I mean you should update the cover letter to make this clear and drop the whole reference to things being temporary, this is a lot more strident than the cover letter is. In any case, that has nothing to do with whether or not we export internal implementation details to a module. Something being in-tree compiled gets to use actually far too many internal interfaces that really should not have been exposed, we've been far too leniant about that, and that's something I want to address (mm has mm/*.h internal-only headers, not sure how we'll deal with that with rust though). Sadly even with in-tree, every interface you make available leads to driver abuse. So something compiled in-tree using X, Y or Z interface doesn't mean that it's correct or even wise, and modularising forces you to rethink that. folio_mkclean() is a great example, we were about to be able to make that mm-internal then 2 more filesystems started using it oops :) > > Alice Cheers, Lorenzo ^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 4/5] ipc: export init_ipc_ns and put_ipc_ns 2026-02-05 10:51 [PATCH 0/5] Make Rust Binder build as a module Alice Ryhl ` (2 preceding siblings ...) 2026-02-05 10:51 ` [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del Alice Ryhl @ 2026-02-05 10:51 ` Alice Ryhl 2026-02-05 10:51 ` [PATCH 5/5] rust_binder: mark ANDROID_BINDER_IPC_RUST tristate Alice Ryhl 4 siblings, 0 replies; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 10:51 UTC (permalink / raw) To: Greg Kroah-Hartman, Carlos Llamas Cc: Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Alice Ryhl These symbols are used by binderfs as part of the info stored with the file system. Signed-off-by: Alice Ryhl <aliceryhl@google.com> --- ipc/msgutil.c | 1 + ipc/namespace.c | 1 + 2 files changed, 2 insertions(+) diff --git a/ipc/msgutil.c b/ipc/msgutil.c index e28f0cecb2ec942a4f6ee93df8384716bd026011..024faedd07c333b23f1e8733833b84ecf5aed9a7 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -30,6 +30,7 @@ struct ipc_namespace init_ipc_ns = { .ns = NS_COMMON_INIT(init_ipc_ns), .user_ns = &init_user_ns, }; +EXPORT_SYMBOL(init_ipc_ns); struct msg_msgseg { struct msg_msgseg *next; diff --git a/ipc/namespace.c b/ipc/namespace.c index 535f16ea40e187a9152a03a7345e00b6c5611dbe..c6355020641a74c3be7737b9da15022b961d8f2a 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -210,6 +210,7 @@ void put_ipc_ns(struct ipc_namespace *ns) schedule_work(&free_ipc_work); } } +EXPORT_SYMBOL(put_ipc_ns); static struct ns_common *ipcns_get(struct task_struct *task) { -- 2.53.0.rc2.204.g2597b5adb4-goog ^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 5/5] rust_binder: mark ANDROID_BINDER_IPC_RUST tristate 2026-02-05 10:51 [PATCH 0/5] Make Rust Binder build as a module Alice Ryhl ` (3 preceding siblings ...) 2026-02-05 10:51 ` [PATCH 4/5] ipc: export init_ipc_ns and put_ipc_ns Alice Ryhl @ 2026-02-05 10:51 ` Alice Ryhl 2026-02-05 13:21 ` Gary Guo 4 siblings, 1 reply; 43+ messages in thread From: Alice Ryhl @ 2026-02-05 10:51 UTC (permalink / raw) To: Greg Kroah-Hartman, Carlos Llamas Cc: Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux, Alice Ryhl Currently Binder only builds as built-in module, but in downstream Android branches we update the build system to make Rust Binder buildable as a module. The same situation applies to distros, as there are many distros that enable Binder for support of apps such as waydroid, which would benefit from the ability to build Binder as a module. Note that although the situation in Android may be temporary - once we no longer have a C implementation, it makes sense for Rust Binder to be built-in. But that will both take a while, and in any case, distros enabling Binder will benefit from it being a module even if Android goes back to built-in. This doesn't mark C Binder buildable as a module. That would require more intrusive Makefile changes as it's built from multiple objects, and I'm not sure there's any way to produce a file called 'binder.ko' containing all of those objects linked together without renaming 'binder.c', as right now there will be naming conflicts between the object built from binder.c, and the object that results from linking binder.o,binderfs.o,binder_alloc.o and so on together. (As an aside, this issue is why the Rust Binder entry-point is called rust_binder_main.rs instead of just rust_binder.rs) Signed-off-by: Alice Ryhl <aliceryhl@google.com> --- drivers/android/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig index e2e402c9d1759c81591473ad02ab7ad011bc61d0..3c1755e53195b0160d0ed244f078eed96e16272c 100644 --- a/drivers/android/Kconfig +++ b/drivers/android/Kconfig @@ -15,7 +15,7 @@ config ANDROID_BINDER_IPC between said processes. config ANDROID_BINDER_IPC_RUST - bool "Rust version of Android Binder IPC Driver" + tristate "Rust version of Android Binder IPC Driver" depends on RUST && MMU && !ANDROID_BINDER_IPC help This enables the Rust implementation of the Binder driver. -- 2.53.0.rc2.204.g2597b5adb4-goog ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH 5/5] rust_binder: mark ANDROID_BINDER_IPC_RUST tristate 2026-02-05 10:51 ` [PATCH 5/5] rust_binder: mark ANDROID_BINDER_IPC_RUST tristate Alice Ryhl @ 2026-02-05 13:21 ` Gary Guo 0 siblings, 0 replies; 43+ messages in thread From: Gary Guo @ 2026-02-05 13:21 UTC (permalink / raw) To: Alice Ryhl, Greg Kroah-Hartman, Carlos Llamas Cc: Alexander Viro, Christian Brauner, Jan Kara, Paul Moore, James Morris, Serge E. Hallyn, Andrew Morton, Dave Chinner, Qi Zheng, Roman Gushchin, Muchun Song, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Danilo Krummrich, kernel-team, linux-fsdevel, linux-kernel, linux-security-module, linux-mm, rust-for-linux On Thu Feb 5, 2026 at 10:51 AM GMT, Alice Ryhl wrote: > Currently Binder only builds as built-in module, but in downstream > Android branches we update the build system to make Rust Binder > buildable as a module. The same situation applies to distros, as there > are many distros that enable Binder for support of apps such as > waydroid, which would benefit from the ability to build Binder as a > module. > > Note that although the situation in Android may be temporary - once we > no longer have a C implementation, it makes sense for Rust Binder to be > built-in. But that will both take a while, and in any case, distros > enabling Binder will benefit from it being a module even if Android goes > back to built-in. > > This doesn't mark C Binder buildable as a module. That would require > more intrusive Makefile changes as it's built from multiple objects, and > I'm not sure there's any way to produce a file called 'binder.ko' > containing all of those objects linked together without renaming > 'binder.c', as right now there will be naming conflicts between the > object built from binder.c, and the object that results from linking > binder.o,binderfs.o,binder_alloc.o and so on together. (As an aside, > this issue is why the Rust Binder entry-point is called > rust_binder_main.rs instead of just rust_binder.rs) > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > --- > drivers/android/Kconfig | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig > index e2e402c9d1759c81591473ad02ab7ad011bc61d0..3c1755e53195b0160d0ed244f078eed96e16272c 100644 > --- a/drivers/android/Kconfig > +++ b/drivers/android/Kconfig > @@ -15,7 +15,7 @@ config ANDROID_BINDER_IPC > between said processes. > > config ANDROID_BINDER_IPC_RUST > - bool "Rust version of Android Binder IPC Driver" > + tristate "Rust version of Android Binder IPC Driver" > depends on RUST && MMU && !ANDROID_BINDER_IPC > help > This enables the Rust implementation of the Binder driver. Hi Alice, AFAIK Rust binder doesn't specifically handle module unloading, so global statics (e.g. CONTEXTS doesn't get dropped). If we're going to build Binder as module, we need to ensure that we have the mechanism in the module macro to prevent unloading of Binder. Best, Gary ^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2026-02-20 0:00 UTC | newest] Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-02-05 10:51 [PATCH 0/5] Make Rust Binder build as a module Alice Ryhl 2026-02-05 10:51 ` [PATCH 1/5] export file_close_fd and task_work_add Alice Ryhl 2026-02-05 11:20 ` Lorenzo Stoakes 2026-02-05 11:42 ` Alice Ryhl 2026-02-05 11:53 ` Lorenzo Stoakes 2026-02-05 13:45 ` Alice Ryhl 2026-02-09 15:21 ` Lorenzo Stoakes 2026-02-10 8:47 ` Alice Ryhl 2026-02-05 11:38 ` Christian Brauner 2026-02-05 11:52 ` Jan Kara 2026-02-05 12:07 ` Alice Ryhl 2026-02-05 10:51 ` [PATCH 2/5] security: export binder symbols Alice Ryhl 2026-02-20 0:00 ` Paul Moore 2026-02-05 10:51 ` [PATCH 3/5] mm: export zap_page_range_single and list_lru_add/del Alice Ryhl 2026-02-05 10:59 ` David Hildenbrand (arm) 2026-02-05 11:04 ` Alice Ryhl 2026-02-05 11:12 ` David Hildenbrand (arm) 2026-02-05 11:18 ` Alice Ryhl 2026-02-05 11:30 ` David Hildenbrand (arm) 2026-02-05 11:29 ` Lorenzo Stoakes 2026-02-05 11:43 ` David Hildenbrand (arm) 2026-02-05 11:57 ` David Hildenbrand (arm) 2026-02-05 12:01 ` Lorenzo Stoakes 2026-02-05 12:06 ` David Hildenbrand (arm) 2026-02-05 12:07 ` Lorenzo Stoakes 2026-02-05 11:57 ` Lorenzo Stoakes 2026-02-05 12:03 ` David Hildenbrand (arm) 2026-02-05 12:12 ` Lorenzo Stoakes 2026-02-05 12:24 ` Miguel Ojeda 2026-02-05 12:28 ` Lorenzo Stoakes 2026-02-05 11:58 ` Alice Ryhl 2026-02-05 12:10 ` Lorenzo Stoakes 2026-02-05 12:13 ` David Hildenbrand (arm) 2026-02-05 12:19 ` Alice Ryhl 2026-02-05 12:24 ` Lorenzo Stoakes 2026-02-05 12:30 ` David Hildenbrand (Arm) 2026-02-09 15:22 ` Lorenzo Stoakes 2026-02-05 12:16 ` Alice Ryhl 2026-02-05 12:07 ` Alice Ryhl 2026-02-05 12:18 ` Lorenzo Stoakes 2026-02-05 10:51 ` [PATCH 4/5] ipc: export init_ipc_ns and put_ipc_ns Alice Ryhl 2026-02-05 10:51 ` [PATCH 5/5] rust_binder: mark ANDROID_BINDER_IPC_RUST tristate Alice Ryhl 2026-02-05 13:21 ` Gary Guo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox