How ti get the size of eBPF map? - ebpf

I'm new to eBPF, I want to insert elements to a BPF_ARRAY, so is there any way to do like C++ push_back() size() function?

Yes and no. You can change elements in an array map (through the system call bpf(BPF_MAP_UPDATE_ELEM, ...)), but you cannot dynamically resize your map at this time (see also this answer), although this might be possible in the future as some work in that direction has been presented before.
So for now you have a fixed-size array that you can update either from your BPF program, or from user space. For the user space side, in C++, you probably want to use libbpf to update your map. You have a low-level wrapper around the syscall in bpf.h, bpf_map_update_elem(), as well as a higher-level function that works on map objects managed by the library, in libbpf.h: bpf_map__update_elem().
To answer to the question from your title: Yes you can obtain the map size, again through the bpf() system call. Libbpf provides a wrapper: bpf_obj_get_info_by_fd(), which fills a struct bpf_map_info from which you can retrieve the size of the map.

Related

ebpf-tc: how to keep unique information inside a ebpf instance when same program is attached to multiple interface

When we pin a MAP, we can able to share information from userspace to ebpf but it is system wide.
But if i want to share different value to different instance from tc ingress/egress (array map with size of 1)
Is there any way to pass argument ?
Map (unpinned unique per instance) - update from userspace
Any other way to communicate from userspace to kernel (while attaching or after)
Really appreciate your help.
Pinning a map doesn't make it system wide. Every map is always accessible system wide, pinning just adds a reference to the file system to make it easier to find and to make sure a map isn't removed even when not in use by any program.
Is there any way to pass argument ?
No, once a program is loaded, only the kernel can pass arguments(contexts) to a program, userspace can only use maps to communicate with eBPF programs.
Map (unpinned unique per instance) - update from userspace
Any userspace program with the right permissions can update any map as long as you can obtain a file descriptor to the map. Map FDs can be obtained:
By creating a new map
By opening a map pin
By using its unique ID (directly or by looping over all loaded maps)
By IPC from another process that already has the FD
Any other way to communicate from userspace to kernel (while attaching or after)
Maps are it. You can rewrite the program before loading it into the kernel by setting constants at specific locations, but not at attach time. One way which might be interesting is that on newer kernels, global data is supported. Which allow you to change the value of variables defined in the global scope from userspace. In this case the global data is packed in a array map with a single key/value.

How can I pass custom data into a MTAudioProcessingTapProcessCallback?

I am successfully using an MTAudioProcessingTap in Swift on MacOS to manipulate my audio routing for both live playback and export. However, the specific routing that should occur at runtime depends on the user's choices. What I would like to be able to do is pass in a pair of Ints to the MTAudioProcessingTapProcessCallback when I create the tap so that I can use a single callback definition that can use those Ints to determine how to do the routing. The problem is that the callback is a C function pointer that can't capture context.
I thought maybe I could use the clientInfo parameter of the MTAudioProcessingTapCallbacks to hold the values I need, but I can't find any documentation on how I can access this parameter from within the MTAudioProcessingTapProcessCallback.
I have 32 possible routing combinations, and unfortunately the only other option I see at this point is declaring 32 separate MTAudioProcessingTapProcessCallbacks, and then selecting which to use when I create the tap. But it would be so much easier for me if I could just have a single MTAudioProcessingTapProcessCallback that makes a simple decision based on passed-in data.
I figured out how it works. In order to access the data inside the clientInfo from within the Process callback:
Inside the MTAudioProcessingTapInitCallback you have to initialize the tapStorageOut with the clientInfo pointer
Inside the Process callback use MTAudioProcessingTapGetStorage(tap) to get that pointer and access the data.

ShardManagement Binary ShardingKey Max Value

I am currently setting up my shardmap manager, shard map ... via the PowerShell script provided here.
While the example uses int as ShardingKey type, I have a binary(16) ShardingKey, does anyone know how to determine and pass a high key of max binary(16) to Add-RangeMapping ?
The Add-RangeMapping function calls the Range(low, high) constructor. In order to create a range with a max high value, it would need to call the Range(low) constructor. So you'll have to edit the Add-RangeMapping function appropriately (or just directly call into the library code without using the Add-RangeMapping function).
The PowerShell helper scripts don't cover the complete Elastic Database Client Library surface area so you may find a few more gaps.

Dynamic Array in Metal(API)?

I am writing an object recognition program. I am using Metal Api.The problem is that i need array list or dynamic array, but there is no dynamic array in Metal. Is there a way to declare one or to implement your own?
There is no way to do dynamic memory allocation inside the Metal kernels (shaders). I'd just define more buffers on the CPU side and pass it to the shader (instead of creating dynamic arrays inside the shaders). Just make sure to change the 'storage mode' to 'private' for the buffers you want to use just in the shader for the intermediate calculations. The 'private' mode mean the buffer is just on the GPU and CPU does not have access to it (and can reduce overhead).

Loading Variables into Functions from Structs in Matlab

Say I have a project which is comprised of:
A main script that handles all of the running of my simulation
Several smaller functions
A couple of structs containing the data
Within the script I will be accessing the functions many times within for loops (some over a thousand times within the minute long simulation). Each function is also looking for data contained with a struct files as part of their calculations, which are usually parameters that are fixed over the course of the simulation, however need to be varied manually between runs to observe the effects.
As typically these functions form the bulk of the runtime I'm trying to save time, as my simulation can't quite run at real-time as it stands (the ultimate goal), and I lose alot of time passing variables/parameters around functions. So I've had three ideas to try and do this:
Load the structs in the main simulation, then pass each variable in turn to the function in the form of a large argument (the current solution).
Load the structs every time the function is called.
Define the structs as global variables.
In terms of both the efficiency of the system (most relevent as the project develops), and possibly as I'm no expert programmer from a "good practise" perspective what is the best solution for this? Is there another option that I have not considered?
As mentioned above in the comments - the 1st item is best one.
Have you used the profiler to find out where you code takes most of its time?
profile on
% run your code
profile viewer
Note: if you are modifying your input struct in your child functions -> this will take more time, but if you are just referencing them then that should not be a problem.
Matlab does what's known as a "lazy copy" when passing arguments between functions. This means that it passes a pointer to the data to the function, rather than creating a new instance of that data, which is very efficient memory- and speed-wise. However, if you make any alteration to that data inside the subroutine, then it has to make a new instance of that argument so as to not overwrite the argument's value in the main function. Your response to matlabgui indicates you're doing just that. So, the subroutine may be making an entire new struct every time it's called, even though it's only modifying a small part of that struct's values.
If your subroutine is altering a small part of the array, then your best bet is to just pass that small part to it, then assign your outputs. For instance,
[modified_array] = somesubroutine(struct.original_array);
struct.original_array=modified_array;
You can also do this in just one line. Conceptually, the less data you pass to the subroutine, the smaller the memory footprint is. I'd also recommend reading up on in-place operations, as it relates to this.
Also, as a general rule, don't use global variables in Matlab. I have not personally experienced, nor read of an instance in which they were genuinely faster.