<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/include/linux/bpf_local_storage.h, branch v7.1-rc6</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v7.1-rc6</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v7.1-rc6'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-04-11T04:22:32+00:00</updated>
<entry>
<title>bpf: Remove gfp_flags plumbing from bpf_local_storage_update()</title>
<updated>2026-04-11T04:22:32+00:00</updated>
<author>
<name>Amery Hung</name>
<email>ameryhung@gmail.com</email>
</author>
<published>2026-04-11T01:54:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=136deea435dc83d7fe2304303bb9bccb54f69bb0'/>
<id>urn:sha1:136deea435dc83d7fe2304303bb9bccb54f69bb0</id>
<content type='text'>
Remove the check that rejects sleepable BPF programs from doing
BPF_ANY/BPF_EXIST updates on local storage. This restriction was added
in commit b00fa38a9c1c ("bpf: Enable non-atomic allocations in local
storage") because kzalloc(GFP_KERNEL) could sleep inside
local_storage-&gt;lock. This is no longer a concern: all local storage
allocations now use kmalloc_nolock() which never sleeps.

In addition, since kmalloc_nolock() only accepts __GFP_ACCOUNT,
__GFP_ZERO and __GFP_NO_OBJ_EXT, the gfp_flags parameter plumbing from
bpf_*_storage_get() to bpf_local_storage_update() becomes dead code.
Remove gfp_flags from bpf_selem_alloc(), bpf_local_storage_alloc() and
bpf_local_storage_update(). Drop the hidden 5th argument from
bpf_*_storage_get helpers, and remove the verifier patching that
injected GFP_KERNEL/GFP_ATOMIC into the fifth argument.

Signed-off-by: Amery Hung &lt;ameryhung@gmail.com&gt;
Link: https://lore.kernel.org/r/20260411015419.114016-4-ameryhung@gmail.com
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
</content>
</entry>
<entry>
<title>bpf: Use kmalloc_nolock() universally in local storage</title>
<updated>2026-04-11T04:22:32+00:00</updated>
<author>
<name>Amery Hung</name>
<email>ameryhung@gmail.com</email>
</author>
<published>2026-04-11T01:54:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=5063e775889948c0475ccdf21c74a6191b7b6482'/>
<id>urn:sha1:5063e775889948c0475ccdf21c74a6191b7b6482</id>
<content type='text'>
Switch to kmalloc_nolock() universally in local storage. Socket local
storage didn't move to kmalloc_nolock() when BPF memory allocator was
replaced by it for performance reasons. Now that kfree_rcu() supports
freeing memory allocated by kmalloc_nolock(), we can move the remaining
local storages to use kmalloc_nolock() and cleanup the cluttered free
paths.

Use kfree() instead of kfree_nolock() in bpf_selem_free_trace_rcu() and
bpf_local_storage_free_trace_rcu(). Both callbacks run in process context
where spinning is allowed, so kfree_nolock() is unnecessary.

Benchmark:

./bench -p 1 local-storage-create --storage-type socket \
  --batch-size {16,32,64}

The benchmark is a microbenchmark stress-testing how fast local storage
can be created. There is no measurable throughput change for socket local
storage after switching from kzalloc() to kmalloc_nolock().

Socket local storage

                 batch  creation speed              diff
---------------  ----   ------------------          ----
Baseline          16    433.9 ± 0.6 k/s
                  32    434.3 ± 1.4 k/s
                  64    434.2 ± 0.7 k/s

After             16    439.0 ± 1.9 k/s             +1.2%
                  32    437.3 ± 2.0 k/s             +0.7%
                  64    435.8 ± 2.5k/s              +0.4%

Also worth noting that the baseline got a 5% throughput boost when sheaf
replaces percpu partial slab recently [0].

[0] https://lore.kernel.org/bpf/20260123-sheaves-for-all-v4-0-041323d506f7@suse.cz/

Signed-off-by: Amery Hung &lt;ameryhung@gmail.com&gt;
Link: https://lore.kernel.org/r/20260411015419.114016-3-ameryhung@gmail.com
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
</content>
</entry>
<entry>
<title>bpf: Lose const-ness of map in map_check_btf()</title>
<updated>2026-02-27T23:39:00+00:00</updated>
<author>
<name>Kumar Kartikeya Dwivedi</name>
<email>memxor@gmail.com</email>
</author>
<published>2026-02-27T22:48:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ae51772b1e94ba1d76db19085957dbccac189c1c'/>
<id>urn:sha1:ae51772b1e94ba1d76db19085957dbccac189c1c</id>
<content type='text'>
BPF hash map may now use the map_check_btf() callback to decide whether
to set a dtor on its bpf_mem_alloc or not. Unlike C++ where members can
opt out of const-ness using mutable, we must lose the const qualifier on
the callback such that we can avoid the ugly cast. Make the change and
adjust all existing users, and lose the comment in hashtab.c.

Signed-off-by: Kumar Kartikeya Dwivedi &lt;memxor@gmail.com&gt;
Link: https://lore.kernel.org/r/20260227224806.646888-3-memxor@gmail.com
Signed-off-by: Alexei Starovoitov &lt;ast@kernel.org&gt;

</content>
</entry>
<entry>
<title>bpf: Switch to bpf_selem_unlink_nofail in bpf_local_storage_{map_free, destroy}</title>
<updated>2026-02-06T22:47:59+00:00</updated>
<author>
<name>Amery Hung</name>
<email>ameryhung@gmail.com</email>
</author>
<published>2026-02-05T22:29:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=0be08389c7f2f9db0194ee666d2e4870886e6ffb'/>
<id>urn:sha1:0be08389c7f2f9db0194ee666d2e4870886e6ffb</id>
<content type='text'>
Take care of rqspinlock error in bpf_local_storage_{map_free, destroy}()
properly by switching to bpf_selem_unlink_nofail().

Both functions iterate their own RCU-protected list of selems and call
bpf_selem_unlink_nofail(). In map_free(), to prevent infinite loop when
both map_free() and destroy() fail to remove a selem from b-&gt;list
(extremely unlikely), switch to hlist_for_each_entry_rcu(). In destroy(),
also switch to hlist_for_each_entry_rcu() since we no longer iterate
local_storage-&gt;list under local_storage-&gt;lock.

bpf_selem_unlink() now becomes dedicated to helpers and syscalls paths
so reuse_now should always be false. Remove it from the argument and
hardcode it.

Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Co-developed-by: Martin KaFai Lau &lt;martin.lau@kernel.org&gt;
Signed-off-by: Amery Hung &lt;ameryhung@gmail.com&gt;
Signed-off-by: Martin KaFai Lau &lt;martin.lau@kernel.org&gt;
Link: https://patch.msgid.link/20260205222916.1788211-12-ameryhung@gmail.com
</content>
</entry>
<entry>
<title>bpf: Support lockless unlink when freeing map or local storage</title>
<updated>2026-02-06T22:47:47+00:00</updated>
<author>
<name>Amery Hung</name>
<email>ameryhung@gmail.com</email>
</author>
<published>2026-02-05T22:29:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=5d800f87d0a5ea1b156c47a4b9fd128479335153'/>
<id>urn:sha1:5d800f87d0a5ea1b156c47a4b9fd128479335153</id>
<content type='text'>
Introduce bpf_selem_unlink_nofail() to properly handle errors returned
from rqspinlock in bpf_local_storage_map_free() and
bpf_local_storage_destroy() where the operation must succeeds.

The idea of bpf_selem_unlink_nofail() is to allow an selem to be
partially linked and use atomic operation on a bit field, selem-&gt;state,
to determine when and who can free the selem if any unlink under lock
fails. An selem initially is fully linked to a map and a local storage.
Under normal circumstances, bpf_selem_unlink_nofail() will be able to
grab locks and unlink a selem from map and local storage in sequeunce,
just like bpf_selem_unlink(), and then free it after an RCU grace period.
However, if any of the lock attempts fails, it will only clear
SDATA(selem)-&gt;smap or selem-&gt;local_storage depending on the caller and
set SELEM_MAP_UNLINKED or SELEM_STORAGE_UNLINKED according to the
caller. Then, after both map_free() and destroy() see the selem and the
state becomes SELEM_UNLINKED, one of two racing caller can succeed in
cmpxchg the state from SELEM_UNLINKED to SELEM_TOFREE, ensuring no
double free or memory leak.

To make sure bpf_obj_free_fields() is done only once and when map is
still present, it is called when unlinking an selem from b-&gt;list under
b-&gt;lock.

To make sure uncharging memory is done only when the owner is still
present in map_free(), block destroy() from returning until there is no
pending map_free().

Since smap may not be valid in destroy(), bpf_selem_unlink_nofail()
skips bpf_selem_unlink_storage_nolock_misc() when called from destroy().
This is okay as bpf_local_storage_destroy() will return the remaining
amount of memory charge tracked by mem_charge to the owner to uncharge.
It is also safe to skip clearing local_storage-&gt;owner and owner_storage
as the owner is being freed and no users or bpf programs should be able
to reference the owner and using local_storage.

Finally, access of selem, SDATA(selem)-&gt;smap and selem-&gt;local_storage
are racy. Callers will protect these fields with RCU.

Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Co-developed-by: Martin KaFai Lau &lt;martin.lau@kernel.org&gt;
Signed-off-by: Amery Hung &lt;ameryhung@gmail.com&gt;
Signed-off-by: Martin KaFai Lau &lt;martin.lau@kernel.org&gt;
Link: https://patch.msgid.link/20260205222916.1788211-11-ameryhung@gmail.com
</content>
</entry>
<entry>
<title>bpf: Prepare for bpf_selem_unlink_nofail()</title>
<updated>2026-02-06T22:29:22+00:00</updated>
<author>
<name>Amery Hung</name>
<email>ameryhung@gmail.com</email>
</author>
<published>2026-02-05T22:29:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c8be3da14718f1e732afcb61e8ee5b78e8d93808'/>
<id>urn:sha1:c8be3da14718f1e732afcb61e8ee5b78e8d93808</id>
<content type='text'>
The next patch will introduce bpf_selem_unlink_nofail() to handle
rqspinlock errors. bpf_selem_unlink_nofail() will allow an selem to be
partially unlinked from map or local storage. Save memory allocation
method in selem so that later an selem can be correctly freed even when
SDATA(selem)-&gt;smap is init to NULL.

In addition, keep track of memory charge to the owner in local storage
so that later bpf_selem_unlink_nofail() can return the correct memory
charge to the owner. Updating local_storage-&gt;mem_charge is protected by
local_storage-&gt;lock.

Finally, extract miscellaneous tasks performed when unlinking an selem
from local_storage into bpf_selem_unlink_storage_nolock_misc(). It will
be reused by bpf_selem_unlink_nofail().

This patch also takes the chance to remove local_storage-&gt;smap, which
is no longer used since commit f484f4a3e058 ("bpf: Replace bpf memory
allocator with kmalloc_nolock() in local storage").

Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Amery Hung &lt;ameryhung@gmail.com&gt;
Signed-off-by: Martin KaFai Lau &lt;martin.lau@kernel.org&gt;
Link: https://patch.msgid.link/20260205222916.1788211-10-ameryhung@gmail.com
</content>
</entry>
<entry>
<title>bpf: Remove unused percpu counter from bpf_local_storage_map_free</title>
<updated>2026-02-06T22:29:18+00:00</updated>
<author>
<name>Amery Hung</name>
<email>ameryhung@gmail.com</email>
</author>
<published>2026-02-05T22:29:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=3417dffb58331d1e7e4f3e30ec95cc0f8114ff10'/>
<id>urn:sha1:3417dffb58331d1e7e4f3e30ec95cc0f8114ff10</id>
<content type='text'>
Percpu locks have been removed from cgroup and task local storage. Now
that all local storage no longer use percpu variables as locks preventing
recursion, there is no need to pass them to bpf_local_storage_map_free().
Remove the argument from the function.

Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Amery Hung &lt;ameryhung@gmail.com&gt;
Signed-off-by: Martin KaFai Lau &lt;martin.lau@kernel.org&gt;
Link: https://patch.msgid.link/20260205222916.1788211-9-ameryhung@gmail.com
</content>
</entry>
<entry>
<title>bpf: Change local_storage-&gt;lock and b-&gt;lock to rqspinlock</title>
<updated>2026-02-06T22:29:04+00:00</updated>
<author>
<name>Amery Hung</name>
<email>ameryhung@gmail.com</email>
</author>
<published>2026-02-05T22:29:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=8dabe34b9d5b1135b084268396ed2267107e64c1'/>
<id>urn:sha1:8dabe34b9d5b1135b084268396ed2267107e64c1</id>
<content type='text'>
Change bpf_local_storage::lock and bpf_local_storage_map_bucket::lock
from raw_spin_lock to rqspinlock.

Finally, propagate errors from raw_res_spin_lock_irqsave() to syscall
return or BPF helper return.

In bpf_local_storage_destroy(), ignore return from
raw_res_spin_lock_irqsave() for now. A later patch will correctly
handle errors correctly in bpf_local_storage_destroy() so that it can
unlink selems even when failing to acquire locks.

For __bpf_local_storage_map_cache(), instead of handling the error,
skip updating the cache.

Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Amery Hung &lt;ameryhung@gmail.com&gt;
Signed-off-by: Martin KaFai Lau &lt;martin.lau@kernel.org&gt;
Link: https://patch.msgid.link/20260205222916.1788211-6-ameryhung@gmail.com
</content>
</entry>
<entry>
<title>bpf: Convert bpf_selem_unlink to failable</title>
<updated>2026-02-06T22:28:59+00:00</updated>
<author>
<name>Amery Hung</name>
<email>ameryhung@gmail.com</email>
</author>
<published>2026-02-05T22:29:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=403e935f915896243ff93f9a2ff44e5bb6619032'/>
<id>urn:sha1:403e935f915896243ff93f9a2ff44e5bb6619032</id>
<content type='text'>
To prepare changing both bpf_local_storage_map_bucket::lock and
bpf_local_storage::lock to rqspinlock, convert bpf_selem_unlink() to
failable. It still always succeeds and returns 0 until the change
happens. No functional change.

Open code bpf_selem_unlink_storage() in the only caller,
bpf_selem_unlink(), since unlink_map and unlink_storage must be done
together after all the necessary locks are acquired.

For bpf_local_storage_map_free(), ignore the return from
bpf_selem_unlink() for now. A later patch will allow it to unlink selems
even when failing to acquire locks.

Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Amery Hung &lt;ameryhung@gmail.com&gt;
Signed-off-by: Martin KaFai Lau &lt;martin.lau@kernel.org&gt;
Link: https://patch.msgid.link/20260205222916.1788211-5-ameryhung@gmail.com
</content>
</entry>
<entry>
<title>bpf: Convert bpf_selem_link_map to failable</title>
<updated>2026-02-06T22:28:55+00:00</updated>
<author>
<name>Amery Hung</name>
<email>ameryhung@gmail.com</email>
</author>
<published>2026-02-05T22:29:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=fd103ffc57c9a3b8b76bc852ffae5eb630a6ded4'/>
<id>urn:sha1:fd103ffc57c9a3b8b76bc852ffae5eb630a6ded4</id>
<content type='text'>
To prepare for changing bpf_local_storage_map_bucket::lock to rqspinlock,
convert bpf_selem_link_map() to failable. It still always succeeds and
returns 0 until the change happens. No functional change.

Acked-by: Alexei Starovoitov &lt;ast@kernel.org&gt;
Signed-off-by: Amery Hung &lt;ameryhung@gmail.com&gt;
Signed-off-by: Martin KaFai Lau &lt;martin.lau@kernel.org&gt;
Link: https://patch.msgid.link/20260205222916.1788211-4-ameryhung@gmail.com
</content>
</entry>
</feed>
