include/asm-generic/pgalloc.h | 2 +- kernel/fork.c | 8 +++++--- mm/vmalloc.c | 8 ++++++-- 3 files changed, 12 insertions(+), 6 deletions(-)
Stacks and page tables are always accessed with the match‑all tag, so assigning a new random tag every time at allocation and setting invalid tag at deallocation time, just adds overhead without improving the detection. With __GFP_SKIP_KASAN the page keeps its poison tag and KASAN_TAG_KERNEL (match-all tag) is stored in the page flags while keeping the poison tag in the hardware. The benefit of it is that 256 tag setting instruction per 4 kB page aren't needed at allocation and deallocation time. Thus match‑all pointers still work, while non‑match tags (other than poison tag) still fault. __GFP_SKIP_KASAN only skips for KASAN_HW_TAGS mode, so coverage is unchanged. Benchmark: The benchmark has two modes. In thread mode, the child process forks and creates N threads. In pgtable mode, the parent maps and faults a specified memory size and then forks repeatedly with children exiting immediately. Thread benchmark: 2000 iterations, 2000 threads: 2.575 s → 2.229 s (~13.4% faster) The pgtable samples: - 2048 MB, 2000 iters 19.08 s → 17.62 s (~7.6% faster) Muhammad Usama Anjum (3): vmalloc: add __GFP_SKIP_KASAN support fork: skip MTE tagging for kernel stacks mm: SKIP KASAN for page table allocations include/asm-generic/pgalloc.h | 2 +- kernel/fork.c | 8 +++++--- mm/vmalloc.c | 8 ++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) -- 2.47.3
On 3/19/26 12:49, Muhammad Usama Anjum wrote: > Stacks and page tables are always accessed with the match‑all tag, > so assigning a new random tag every time at allocation and setting > invalid tag at deallocation time, just adds overhead without improving > the detection. > > With __GFP_SKIP_KASAN the page keeps its poison tag and KASAN_TAG_KERNEL > (match-all tag) is stored in the page flags while keeping the poison tag > in the hardware. The benefit of it is that 256 tag setting instruction > per 4 kB page aren't needed at allocation and deallocation time. > > Thus match‑all pointers still work, while non‑match tags (other than > poison tag) still fault. > > __GFP_SKIP_KASAN only skips for KASAN_HW_TAGS mode, so coverage is > unchanged. > > Benchmark: > The benchmark has two modes. In thread mode, the child process forks > and creates N threads. In pgtable mode, the parent maps and faults a > specified memory size and then forks repeatedly with children exiting > immediately. > > Thread benchmark: > 2000 iterations, 2000 threads: 2.575 s → 2.229 s (~13.4% faster) > > The pgtable samples: > - 2048 MB, 2000 iters 19.08 s → 17.62 s (~7.6% faster) As discussed offline, I think we should look into finding a better name for __GFP_SKIP_KASAN now that we are using it more broadly. It's confusing. The semantics are: * Only applies to HW KASAN right now. Otherwise it's ignored. So it doesn't give any guarantees. * Will currently leave memory tagged with some tag (poisoned), but tag checks will be disabled by using the match-all pointer. After pondering about that for a while, I realized that today, all memory is tagged by default, and __GFP_SKIP_KASAN is our mechanism to request memory that will not be tag-checked (close to if it would be not tagged). Is there a real difference to getting untagged memory, if supported by the architecture. So I was wondering if __GFP_UNTAGGED: if possible, return memory that is either untagged or that is tagged but has tag checks disabled when accessed through page_address(). Using this flag can speed up page allocation and freeing, and can reduce runtime overhead by not performing page checking. For now, only considered with HW-tag based KASAN. Would be the right thing to do. Assuming we could/would ever change the default from "all memory is tagged" to "all memory is untagged", we could similarly introduce: __GFP_TAGGED: if possible, return memory that is tagged and and has tag checks enabled. We could make it clearer that there are no guarantees. Like calling it __GFP_PREF_UNTAGGED / __GFP_PREF_TAGGED. (__GFP_TAGGED would obviously be something for the future) -- Cheers, David
On 20/03/2026 8:53 am, David Hildenbrand (Arm) wrote: > On 3/19/26 12:49, Muhammad Usama Anjum wrote: >> Stacks and page tables are always accessed with the match‑all tag, >> so assigning a new random tag every time at allocation and setting >> invalid tag at deallocation time, just adds overhead without improving >> the detection. >> >> With __GFP_SKIP_KASAN the page keeps its poison tag and KASAN_TAG_KERNEL >> (match-all tag) is stored in the page flags while keeping the poison tag >> in the hardware. The benefit of it is that 256 tag setting instruction >> per 4 kB page aren't needed at allocation and deallocation time. >> >> Thus match‑all pointers still work, while non‑match tags (other than >> poison tag) still fault. >> >> __GFP_SKIP_KASAN only skips for KASAN_HW_TAGS mode, so coverage is >> unchanged. >> >> Benchmark: >> The benchmark has two modes. In thread mode, the child process forks >> and creates N threads. In pgtable mode, the parent maps and faults a >> specified memory size and then forks repeatedly with children exiting >> immediately. >> >> Thread benchmark: >> 2000 iterations, 2000 threads: 2.575 s → 2.229 s (~13.4% faster) >> >> The pgtable samples: >> - 2048 MB, 2000 iters 19.08 s → 17.62 s (~7.6% faster) > > As discussed offline, I think we should look into finding a better name > for __GFP_SKIP_KASAN now that we are using it more broadly. It's confusing. Agreed that its confusing and the name doesn't show its under-the-hood usage. > > The semantics are: > * Only applies to HW KASAN right now. Otherwise it's ignored. So it > doesn't give any guarantees. > * Will currently leave memory tagged with some tag (poisoned), but > tag checks will be disabled by using the match-all pointer. > > After pondering about that for a while, I realized that today, all > memory is tagged by default, and __GFP_SKIP_KASAN is our mechanism to > request memory that will not be tag-checked (close to if it would be not > tagged). KASAN uses the poisoning and un-poisoning terminologies. It depends upon the type of KASAN enabled that how poisoning/unpoisoning is done. > > Is there a real difference to getting untagged memory, if supported by > the architecture. > > So I was wondering if > > __GFP_UNTAGGED: if possible, return memory that is either > untagged or that is tagged but has tag checks > disabled when accessed through page_address(). > Using this flag can speed up page allocation > and freeing, and can reduce runtime overhead > by not performing page checking. For now, > only considered with HW-tag based KASAN. Its again confusing as __GFP_UNTAGGED will not return untagged memory in case of KASAN_SW_TAGS. As __GFP_SKIP_KASAN skips only for HW_TAGS mode, the more appropriate name may be: __GFP_SKIP_HW_POSION No matter the final name, it may be worth the effort to rename / do better handling of this in the code. Let's keep it a separate from this series. > > Would be the right thing to do. > > Assuming we could/would ever change the default from "all memory is > tagged" to "all memory is untagged", we could similarly introduce: > > __GFP_TAGGED: if possible, return memory that is tagged and > and has tag checks enabled. > > We could make it clearer that there are no guarantees. Like calling it > __GFP_PREF_UNTAGGED / __GFP_PREF_TAGGED. > > > (__GFP_TAGGED would obviously be something for the future) >
On 3/23/26 16:06, Muhammad Usama Anjum wrote: > On 20/03/2026 8:53 am, David Hildenbrand (Arm) wrote: >> On 3/19/26 12:49, Muhammad Usama Anjum wrote: >>> Stacks and page tables are always accessed with the match‑all tag, >>> so assigning a new random tag every time at allocation and setting >>> invalid tag at deallocation time, just adds overhead without improving >>> the detection. >>> >>> With __GFP_SKIP_KASAN the page keeps its poison tag and KASAN_TAG_KERNEL >>> (match-all tag) is stored in the page flags while keeping the poison tag >>> in the hardware. The benefit of it is that 256 tag setting instruction >>> per 4 kB page aren't needed at allocation and deallocation time. >>> >>> Thus match‑all pointers still work, while non‑match tags (other than >>> poison tag) still fault. >>> >>> __GFP_SKIP_KASAN only skips for KASAN_HW_TAGS mode, so coverage is >>> unchanged. >>> >>> Benchmark: >>> The benchmark has two modes. In thread mode, the child process forks >>> and creates N threads. In pgtable mode, the parent maps and faults a >>> specified memory size and then forks repeatedly with children exiting >>> immediately. >>> >>> Thread benchmark: >>> 2000 iterations, 2000 threads: 2.575 s → 2.229 s (~13.4% faster) >>> >>> The pgtable samples: >>> - 2048 MB, 2000 iters 19.08 s → 17.62 s (~7.6% faster) >> >> As discussed offline, I think we should look into finding a better name >> for __GFP_SKIP_KASAN now that we are using it more broadly. It's confusing. > Agreed that its confusing and the name doesn't show its under-the-hood usage. > And I think I finally realized that __GFP_SKIP_KASAN is used for two independent use cases, something that really must be sorted out. >> >> The semantics are: >> * Only applies to HW KASAN right now. Otherwise it's ignored. So it >> doesn't give any guarantees. >> * Will currently leave memory tagged with some tag (poisoned), but >> tag checks will be disabled by using the match-all pointer. >> >> After pondering about that for a while, I realized that today, all >> memory is tagged by default, and __GFP_SKIP_KASAN is our mechanism to >> request memory that will not be tag-checked (close to if it would be not >> tagged). > KASAN uses the poisoning and un-poisoning terminologies. It depends upon > the type of KASAN enabled that how poisoning/unpoisoning is done. And that's an implementation detail. A random memory allocation shouldn't have to know what KASAN or POISONING is. :) > >> >> Is there a real difference to getting untagged memory, if supported by >> the architecture. >> >> So I was wondering if >> >> __GFP_UNTAGGED: if possible, return memory that is either >> untagged or that is tagged but has tag checks >> disabled when accessed through page_address(). >> Using this flag can speed up page allocation >> and freeing, and can reduce runtime overhead >> by not performing page checking. For now, >> only considered with HW-tag based KASAN. > Its again confusing as __GFP_UNTAGGED will not return untagged memory > in case of KASAN_SW_TAGS. > > As __GFP_SKIP_KASAN skips only for HW_TAGS mode, the more appropriate name > may be: > __GFP_SKIP_HW_POSION Also not really the right fit I think. > > No matter the final name, it may be worth the effort to rename / do better > handling of this in the code. Let's keep it a separate from this series. Well, the point I am making is that (1) you are adding more users of __GFP_SKIP_KASAN (2) __GFP_SKIP_KASAN is a mess I'll try to sort that out, but be prepared that the flag name might change underneath your feet :) -- Cheers, David
On Thu, 19 Mar 2026 11:49:43 +0000 Muhammad Usama Anjum <usama.anjum@arm.com> wrote: > Stacks and page tables are always accessed with the match‑all tag, > so assigning a new random tag every time at allocation and setting > invalid tag at deallocation time, just adds overhead without improving > the detection. > > With __GFP_SKIP_KASAN the page keeps its poison tag and KASAN_TAG_KERNEL > (match-all tag) is stored in the page flags while keeping the poison tag > in the hardware. The benefit of it is that 256 tag setting instruction > per 4 kB page aren't needed at allocation and deallocation time. > > Thus match‑all pointers still work, while non‑match tags (other than > poison tag) still fault. > > __GFP_SKIP_KASAN only skips for KASAN_HW_TAGS mode, so coverage is > unchanged. > Some questions from Sashiko: https://sashiko.dev/#/patchset/20260319114952.3241359-1-usama.anjum%40arm.com
On 20/03/2026 3:10 am, Andrew Morton wrote: > * # Be careful, this email looks suspicious; * Out of Character: The sender is exhibiting a significant deviation from their usual behavior, this may indicate that their account has been compromised. Be extra cautious before opening links or attachments. * > On Thu, 19 Mar 2026 11:49:43 +0000 Muhammad Usama Anjum <usama.anjum@arm.com> wrote: > >> Stacks and page tables are always accessed with the match‑all tag, >> so assigning a new random tag every time at allocation and setting >> invalid tag at deallocation time, just adds overhead without improving >> the detection. >> >> With __GFP_SKIP_KASAN the page keeps its poison tag and KASAN_TAG_KERNEL >> (match-all tag) is stored in the page flags while keeping the poison tag >> in the hardware. The benefit of it is that 256 tag setting instruction >> per 4 kB page aren't needed at allocation and deallocation time. >> >> Thus match‑all pointers still work, while non‑match tags (other than >> poison tag) still fault. >> >> __GFP_SKIP_KASAN only skips for KASAN_HW_TAGS mode, so coverage is >> unchanged. >> > > Some questions from Sashiko: > https://uk01.z.antigena.com/l/sS6fsklhbbK-vAbd4-t3S20GiqcWENbKuEm9JdfcHhXGvSkAuP_tTYRVNNEFkNyqNy6Th_W67uq4HpyPCykcGaYKaeMj7OPiFdbYLta2AQ6H4~yy59q32QAKn-zpc1DtUKnRNXkTGRIvJMOH217hIWTkitNDDPLzALLhD6vG1MnteYIid8KfwK4pfDahLHbmvBU1WWp6d3BG53WUdBJ4ONjb2PDTe4JdIvW0uWnju-HL5hb > I've updated descriptions/patches in answer to those concerns. Thanks, Usama
© 2016 - 2026 Red Hat, Inc.