Convert BpfMap native methods to use @FastNative to reduce JNI overhead.
Refactor synchronizeKernelRCU() to be @CriticalNative for maximum
performance by changing its error handling to return an error code
instead of throwing directly from native code.
(In practice we don't expect it to *ever* fail)
FYI:
@FastNative and @CriticalNative are Android-specific annotations
that signal to the ART runtime to use a lower-overhead JNI transition,
resulting in better performance.
A standard JNI call tells the Garbage Collector (GC) that the thread
is transitioning to a 'Native' state. This is a signal to the GC that
the thread might be busy for a while and shouldn't be suspended arbitrarily.
@FastNative is for short, quick functions:
This provides a moderately faster JNI call (thread is still 'Runnable').
The native function signature remains the same as a standard JNI method,
and it can still access the JNIEnv* to interact with Java objects
or throw exceptions.
@CriticalNative is for short, quick & trivial functions:
This provides the fastest possible JNI transition and is intended
for simple, performance-critical leaf functions.
It comes with strict requirements:
- The native method cannot throw exceptions, create Java objects,
or make any other JNI calls.
- All arguments and the return type must be primitive, ie:
jboolean [bool]
jbyte [s8]
jchar [u16]
jshort [s16]
jint [s32]
jlong [s64]
jfloat [32-bit]
jdouble [64-bit]
void
Java objects like String or byte[] are not allowed.
Because of these restrictions, the native C++ function signature
must not include JNIEnv* or jobject/jclass parameters.
(This likely also means it must be 'static')
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I9b6107b26086df2e87218ff9274593e9f2eb6b0b
Maciej Żenczykowskicommited 2025-08-12 15:28:05 -07:00
This is the case (by code inspection): this map is read/written
by C++ jni code, but only read from java.
Getting rid of the java read (used in test/dump code only afaict)
would be annoying due to needing to return a java String from jni.
As such lets just flag it as R/O, this will allow write-through
caching in jni.
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Iadf0a96f3100d32ea4ffd423b5293c6f2de706cb
Maciej Żenczykowskicommited 2025-08-11 23:44:42 -07:00
In practice this is already the case... If uname() execution
fails, or we fail to parse the result, we won't pass the
4.9+ required check in NetBpfLoad, which is required on S+,
and mainline no longer supports anything <S anyway.
We don't require subversion as technically "4.9" (ie. 4.9.0)
is enough for almost all usecases, although in practice I would
expect there will always be an LTS subversion present.
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I66a5eba5c7bcf9bd51997db93c0fefc8104945eb
Maciej Żenczykowskicommited 2025-08-11 21:27:04 -07:00
(this was basically an oversight, nothing should be setting this)
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I6e36d9cb7522272e4a725e77b630b43cb6a1494d
Maciej Żenczykowskicommited 2025-08-11 20:58:15 -07:00
(unfortunately need to keep kernelVersion() around for some uses outside of p/m/C)
The goal of this is to make isAtLeastKernelVersion() checks
cheaper. Currently they all have to check that we've already
parsed uname...
We use that all over the place, even at runtime in BpfMap.h.
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Iaf53fc1e36eb9f88df20c39643cbd53f420ded4e
Maciej Żenczykowskicommited 2025-08-11 15:12:52 -07:00
(in the future consume() can be changed to use kernel bpf map bulk api)
Test: TreeHugger, atest libnetworkstats_test
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I43c3e7139cf38058da4c187d1cfeec4bf7fb0ca1
Maciej Żenczykowskicommited 2025-08-11 12:45:51 -07:00
Note that we no longer need the (void*) casts, this is because:
MAKE_JNI_NATIVE_METHOD() checks function args match
MAKE_JNI_NATIVE_METHOD_AUTOSIG() autogenerates the signature
Additionally:
nativeGetTotalStat()
nativeGetIfaceStat()
nativeGetUidStat()
should be faster now, by virtue of caching a bunch of calls.
This more-or-less mirrors what was already done in the other file.
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I5a715d15ca5c01b625b8b7a62bc0e10bc0cc213f
Maciej Żenczykowskicommited 2025-08-10 10:34:13 -07:00
Note: this is not quite a no-op, as we no longer do the ifname
lookup, which could (but shouldn't) fail and cause us to ignore the stats
(for that interface).
But since it shouldn't ever fail, the value lookup should basically always
happen. Switching to forAll() will allow bulk api optimization...
Test: TreeHugger, atest libbpf_android_test libnetworkstats_test netd_updatable_unit_test
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Id30fa1d2b4f30c5b526b5eba80e401d1a201d95d
Maciej Żenczykowskicommited 2025-08-09 19:18:48 -07:00
switch some iterate to forAll()/consume()
Currently we only use:
BPF_MAP_LOOKUP_ELEM
BPF_MAP_UPDATE_ELEM
BPF_MAP_DELETE_ELEM
BPF_MAP_GET_NEXT_KEY
Our implementation does:
getFirstKey() -> BPF_MAP_GET_NEXT_KEY (with empty key, maybe newer kernels would accept null too)
getNextKey(K) -> BPF_MAP_GET_NEXT_KEY
readValue(K) -> BPF_MAP_LOOKUP_ELEM
iterate(f(K)) -> getFirstKey(), loop { getNextKey(K) }
forAll(f(K)) -> iterate(f(K))
iterate(f(K, V)) -> getFirstKey(), loop { getNextKey(K) readValue(K) }
forAll(f(K, V)) -> iterate(f(K, V))
isEmpty() -> getFirstKey()
writeValue(K, V) -> BPF_MAP_UPDATE_ELEM
deleteValue(K) -> BPF_MAP_DELETE_ELEM
clear() -> loop { getFirstKey() deleteValue(K) }
consume(f(K, V)) -> iterate(f(K, V) + deleteValue(K))
but bpf on newer kernels also supports:
BPF_MAP_LOOKUP_AND_DELETE_ELEM
and batch operations:
BPF_MAP_LOOKUP_BATCH
BPF_MAP_LOOKUP_AND_DELETE_BATCH
BPF_MAP_UPDATE_BATCH
BPF_MAP_DELETE_BATCH
that we don't currently use.
These can be utilized to lower the number of system calls:
- iterate(f(K, V)) might be able to use LOOPUP_BATCH(1)
- forAll() can probably use LOOKUP_BATCH(many)
- consume() can probably use one of LOOKUP_AND_DELETE_ELEM or LOOKUP_AND_DELETE_BATCH
UPDATE_BATCH seems like it could also be useful, though harder
to see how to make it useful from a clean API perspective...
(and obviously for bpf map ARRAYs [and thus bitmaps], mmap() is simply much better...)
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I2c142319c365aa1b9585256e2c604b221ba18c21
Maciej Żenczykowskicommited 2025-08-09 19:02:56 -07:00
(we've deleted the GTS test, so no need for this simple demo case)
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I7f5a060f53ac97d55f533aea7a8148d3c091856d
Maciej Żenczykowskicommited 2025-08-09 16:04:17 -07:00
which allows writes, but not deletes.
This is technically what bpf map arrays are capable of.
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I1f73bea5428c190af17442539c296282ce9e0786
Maciej Żenczykowskicommited 2025-08-09 16:03:46 -07:00
It's so much better to just pass in the map (if needed)
as part of the lambda capture...
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: If16fa9c8d0ade41628dc4f7ac1fa73127001b6b1
Maciej Żenczykowskicommited 2025-08-09 14:25:34 -07:00
Annotate APFv6 multi-device tests with `@CddTest`.
This marks these tests for compliance with specific CDD requirements.
Flag: EXEMPT test only
Bug: 437029299
Test: atest CtsConnectivityMultiDevicesTestCases:ApfV6Test
Change-Id: I686ca609c3f34daf106673e429c49b8776c97923
Annotate APFv4 multi-device tests with `@CddTest`.
This marks these tests for compliance with specific CDD requirements.
Flag: EXEMPT test only
Bug: 437034146
Test: atest CtsConnectivityMultiDevicesTestCases:ApfV4Test
Change-Id: Ibdd4c1652e21a708d5ddde79ecedbe258e318ac3
Perhaps not the best example, but virtually free considering
a bitmap of 64K bits is 8KiB no matter what.
Kernel will allocate:
1 page for internal metadata (rounded up to a full page)
N pages rounded up from array size, which is:
number of elements (65536 bits / 64 bits per u64) = 1024
* element size (u64 rounded up to a multiple of 8) = 8
= 8192
This rounding up is unique to *mmapable* arrays.
thus on 4KiB page size: 12 KiB - waste is at most a few (<4) KiB
and on 16KiB page size: 32 KiB - which isn't great, but well that's 16KiB...
(presumably 16KiB is being used on devices with a lot of ram,
where performance matters more than a little ram waste)
Note: AFAICT a kernel bpf program R/W map cannot be mapped R/O
into userspace, as the permissions on the page mapping would conflict.
(and obviously you cannot map R/W if you have only R/O access)
I'm not sure if this is architecture specific,
or simply an implementation limitation, but it is what I observed.
I think it's likely a missing kernel feature (even on 6.12)...
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I609ae61e17917ff441cac10a9b29af3fcacb53c5
Maciej Żenczykowskicommited 2025-08-07 15:54:01 -07:00
automatically fall back for older kernels
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ice377331442f71fa69f086a3be8a8c10cbc6575f
Maciej Żenczykowskicommited 2025-08-07 15:53:42 -07:00
This is more legible then a series of if's,
although thus require manually adding support for new map types.
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I8900eb8ced5e4a1cb161b49e5c68d2effe36af57
Maciej Żenczykowskicommited 2025-08-07 15:53:05 -07:00
(that this was missing appears to be an oversight)
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Icd424324db11e56f820817f890985155d639175d
Maciej Żenczykowskicommited 2025-08-07 15:52:52 -07:00
(mostly autogenerated, with minor tweaks to make it build)
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I2065c3fc6d4d37663a0a52281deb7624fd5c801d
Maciej Żenczykowskicommited 2025-08-07 15:52:35 -07:00
(mostly autogenerated, with minor tweaks to make it build)
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Idb3706d022c3fbd86fd3abd800ff5eee8edda3cc
Maciej Żenczykowskicommited 2025-08-07 15:51:40 -07:00
(mostly autogenerated, with minor tweaks to make it build)
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Id2ffe0df6526a6377806464e902b8e8f87a43c62
Maciej Żenczykowskicommited 2025-08-07 15:50:48 -07:00
(mostly autogenerated, with minor tweaks to make it build)
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I5a5ba231cb38886b9b681b4c08d89a18ad418f23
Maciej Żenczykowskicommited 2025-08-07 15:48:28 -07:00
(mostly autogenerated, with minor tweaks to make it build)
Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I5a5ba231cb38886b9b681b4c08d89a18ad418f23
Maciej Żenczykowskicommited 2025-08-07 14:02:20 -07:00
Annotate APFv4 and APFv6 multi-device tests with `@VsrTest`.
This marks these tests for compliance with specific VSR requirements,
Flag: EXEMPT test only
Test: atest CtsConnectivityMultiDevicesTestCases:ApfV4Test
Test: atest CtsConnectivityMultiDevicesTestCases:ApfV6Test
Test: ./cts-tradefed run cts \
-m CtsConnectivityMultiDevicesTestCases \
-t ApfV4Test --shard-count 2
Test: ./cts-tradefed run cts \
-m CtsConnectivityMultiDevicesTestCases \
-t ApfV6Test --shard-count 2
Change-Id: I864aa65f6f4d584c4f8077f98aac0b0da8e501c8
This patch add *Proto suffix for some proto message in
NetworkConfigStoreProto to avoid name conflicts with names in
android.net package.
Test: atest ConnectivityCoverageTests
Bug: 397536853
Flag: EXEMPT mainline
Change-Id: I4f826511bcab0fcd3b154bbc349a062fd4841321
AServiceManager_waitForService sytem APIs currently only callable
via dlsym(): b/376759605. When built with sdk_version current,
the NDK stubs for "sdk" variants only include NDK APIs,
excluding #systemapi APIs.
Flag: EXEMPT Mechanical refactors
Test: atest ServiceManagerWrapperIntegrationTest
Change-Id: I48f690d771c7905e79e463617ded772f753cc854
Mark Chienauthored and Patrick Rohrcommited 2025-08-06 10:44:39 -07:00
ConnectivityService would be centralized location for deciding local
network so for this effort adding isLocalRoute parameter to RouteInfoParcel
Bug: 394308861
Test: Manually tested.
Test: atest ConnectivityCoverageTests
Flag: EXEMPT Using device config kill-switch
Change-Id: I3ed34f96af1cbd7d8645a6c19e696a75525ce68a
Some builds (e.g. MSVC) use `#define interface struct` which causes
issues with the field or argument name `interface`.
Change-Id: If18b00028818337c9fabe4a271c570f456d62a9a
Test: Build
Flag: EXEMPT PURE_REFACTOR
Introduce a 3-second delay in each packet send.
Before sending each packet, wait for 3 seconds to give the
firmware time to turn on the APF.
The firmware may have throughput calculation logic that
depends on a certain time window.
Flag: EXEMPT test only
Bug: 434614102
Test: atest CtsConnectivityMultiDevicesTestCases:ApfV6Test
Test: ./cts-tradefed run commandAndExit cts \
-m CtsConnectivityMultiDevicesTestCases \
-t ApfV6Test --shard-count 2
Change-Id: I0807562cd87cbfe90c90d48cf2d0e41673c153b0