All of lore.kernel.org
 help / color / mirror / Atom feed
* HASH_OF_MAPS inner map allocation from BPF
@ 2020-09-04 14:56 Borna Cafuk
  2020-09-04 22:47 ` Alexei Starovoitov
  0 siblings, 1 reply; 9+ messages in thread
From: Borna Cafuk @ 2020-09-04 14:56 UTC (permalink / raw)
  To: bpf; +Cc: Luka Perkov

Hello everyone,

Judging by [0], the inner maps in BPF_MAP_TYPE_HASH_OF_MAPS can only be created
from the userspace. This seems quite limiting in regard to what can be done
with them.

Are there any plans to allow for creating the inner maps from BPF programs?

[0] https://stackoverflow.com/a/63391528

Best regards,
Borna Cafuk

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: HASH_OF_MAPS inner map allocation from BPF
  2020-09-04 14:56 HASH_OF_MAPS inner map allocation from BPF Borna Cafuk
@ 2020-09-04 22:47 ` Alexei Starovoitov
       [not found]   ` <CAFLU3KstRTXs3nwyE8uQY7q9k-sRr1yKCtOQX3gMq3nsxnwHXw@mail.gmail.com>
  2020-09-07 13:13   ` Borna Cafuk
  0 siblings, 2 replies; 9+ messages in thread
From: Alexei Starovoitov @ 2020-09-04 22:47 UTC (permalink / raw)
  To: Borna Cafuk; +Cc: bpf, Luka Perkov, KP Singh, Martin KaFai Lau

On Fri, Sep 4, 2020 at 7:57 AM Borna Cafuk <borna.cafuk@sartura.hr> wrote:
>
> Hello everyone,
>
> Judging by [0], the inner maps in BPF_MAP_TYPE_HASH_OF_MAPS can only be created
> from the userspace. This seems quite limiting in regard to what can be done
> with them.
>
> Are there any plans to allow for creating the inner maps from BPF programs?
>
> [0] https://stackoverflow.com/a/63391528

Did you ask that question or your use case is different?
Creating a new map for map_in_map from bpf prog can be implemented.
bpf_map_update_elem() is doing memory allocation for map elements.
In such a case calling this helper on map_in_map can, in theory, create a new
inner map and insert it into the outer map.

But if your use case it what stackoverflow says:
"
SEC("lsm/sb_alloc_security")
int BPF_PROG(sb_alloc_security, struct super_block *sb) {
    uuid_t key = sb->s_uuid; // use super block UUID as key to the outer_map
    // If key does not exist in outer_map,
    // create a new inner map and insert it
    // into the outer_map with the key
}
"
Then it would be more efficient, faster, easier to use if you could
extend the kernel with per-sb local storage.
We already have socket- and inode- local storage.
Other kernel data structures will fit the same infra.
You wouldn't need to hook into sb_alloc_security either.
From other lsm hooks you'll ask for super_block-local_stoarge and scratch
memory will be allocated on demand and automatically freed with sb.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: HASH_OF_MAPS inner map allocation from BPF
       [not found]   ` <CAFLU3KstRTXs3nwyE8uQY7q9k-sRr1yKCtOQX3gMq3nsxnwHXw@mail.gmail.com>
@ 2020-09-05 14:57     ` KP Singh
  0 siblings, 0 replies; 9+ messages in thread
From: KP Singh @ 2020-09-05 14:57 UTC (permalink / raw)
  To: Alexei Starovoitov; +Cc: Borna Cafuk, bpf, Luka Perkov, Martin KaFai Lau

[+lists, format=plain text]

On Sat, Sep 5, 2020 at 4:48 PM KP Singh <kpsingh@google.com> wrote:
>
>
>
> On Sat, Sep 5, 2020 at 12:47 AM Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
>>
>> On Fri, Sep 4, 2020 at 7:57 AM Borna Cafuk <borna.cafuk@sartura.hr> wrote:
>> >
>> > Hello everyone,
>> >
>> > Judging by [0], the inner maps in BPF_MAP_TYPE_HASH_OF_MAPS can only be created
>> > from the userspace. This seems quite limiting in regard to what can be done
>> > with them.
>> >
>> > Are there any plans to allow for creating the inner maps from BPF programs?
>> >
>> > [0] https://stackoverflow.com/a/63391528
>>
>> Did you ask that question or your use case is different?
>> Creating a new map for map_in_map from bpf prog can be implemented.
>> bpf_map_update_elem() is doing memory allocation for map elements.
>> In such a case calling this helper on map_in_map can, in theory, create a new
>> inner map and insert it into the outer map.
>>
>> But if your use case it what stackoverflow says:
>> "
>> SEC("lsm/sb_alloc_security")
>> int BPF_PROG(sb_alloc_security, struct super_block *sb) {
>>     uuid_t key = sb->s_uuid; // use super block UUID as key to the outer_map
>>     // If key does not exist in outer_map,
>>     // create a new inner map and insert it
>>     // into the outer_map with the key
>> }
>> "
>
>
> Indeed, if you want to associate some information with super_block objects
> in LSM programs, local storage fits better.
>
> It would help if you can shed some more light on your use case.
>
>> Then it would be more efficient, faster, easier to use if you could
>> extend the kernel with per-sb local storage.
>
>
> Now that we have generalized local storage, this should not be much work.
>
> Please have a look at
> https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/kernel/bpf/bpf_inode_storage.c
>
> and the example in:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/tools/testing/selftests/bpf/progs/local_storage.c#n121
>
> We will need something similar for super_block as well.
>
> - KP
>
>> We already have socket- and inode- local storage.
>> Other kernel data structures will fit the same infra.
>> You wouldn't need to hook into sb_alloc_security either.
>> From other lsm hooks you'll ask for super_block-local_stoarge and scratch
>> memory will be allocated on demand and automatically freed with sb.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: HASH_OF_MAPS inner map allocation from BPF
  2020-09-04 22:47 ` Alexei Starovoitov
       [not found]   ` <CAFLU3KstRTXs3nwyE8uQY7q9k-sRr1yKCtOQX3gMq3nsxnwHXw@mail.gmail.com>
@ 2020-09-07 13:13   ` Borna Cafuk
  2020-09-07 13:32     ` Toke Høiland-Jørgensen
  1 sibling, 1 reply; 9+ messages in thread
From: Borna Cafuk @ 2020-09-07 13:13 UTC (permalink / raw)
  To: Alexei Starovoitov; +Cc: bpf, Luka Perkov, kpsingh

On Sat, Sep 5, 2020 at 12:47 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Sep 4, 2020 at 7:57 AM Borna Cafuk <borna.cafuk@sartura.hr> wrote:
> >
> > Hello everyone,
> >
> > Judging by [0], the inner maps in BPF_MAP_TYPE_HASH_OF_MAPS can only be created
> > from the userspace. This seems quite limiting in regard to what can be done
> > with them.
> >
> > Are there any plans to allow for creating the inner maps from BPF programs?
> >
> > [0] https://stackoverflow.com/a/63391528
>
> Did you ask that question or your use case is different?
> Creating a new map for map_in_map from bpf prog can be implemented.
> bpf_map_update_elem() is doing memory allocation for map elements.
> In such a case calling this helper on map_in_map can, in theory, create a new
> inner map and insert it into the outer map.

No, it wasn't me who asked that question, but it seemed close enough to
my issue. My use case calls for modifying the syscount example from BCC[1].

The idea is to have an outer map where the keys are PIDs, and inner maps where
the keys are system call numbers. This would enable tracking the number of
syscalls made by each process and the makeup of those calls for all processes
simultaneously.

[1] https://github.com/iovisor/bcc/blob/master/libbpf-tools/syscount.bpf.c


>
> But if your use case it what stackoverflow says:
> "
> SEC("lsm/sb_alloc_security")
> int BPF_PROG(sb_alloc_security, struct super_block *sb) {
>     uuid_t key = sb->s_uuid; // use super block UUID as key to the outer_map
>     // If key does not exist in outer_map,
>     // create a new inner map and insert it
>     // into the outer_map with the key
> }
> "
> Then it would be more efficient, faster, easier to use if you could
> extend the kernel with per-sb local storage.
> We already have socket- and inode- local storage.
> Other kernel data structures will fit the same infra.
> You wouldn't need to hook into sb_alloc_security either.
> From other lsm hooks you'll ask for super_block-local_stoarge and scratch
> memory will be allocated on demand and automatically freed with sb.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: HASH_OF_MAPS inner map allocation from BPF
  2020-09-07 13:13   ` Borna Cafuk
@ 2020-09-07 13:32     ` Toke Høiland-Jørgensen
  2020-09-09  9:49       ` Borna Cafuk
  0 siblings, 1 reply; 9+ messages in thread
From: Toke Høiland-Jørgensen @ 2020-09-07 13:32 UTC (permalink / raw)
  To: Borna Cafuk, Alexei Starovoitov; +Cc: bpf, Luka Perkov, kpsingh

Borna Cafuk <borna.cafuk@sartura.hr> writes:

> On Sat, Sep 5, 2020 at 12:47 AM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
>>
>> On Fri, Sep 4, 2020 at 7:57 AM Borna Cafuk <borna.cafuk@sartura.hr> wrote:
>> >
>> > Hello everyone,
>> >
>> > Judging by [0], the inner maps in BPF_MAP_TYPE_HASH_OF_MAPS can only be created
>> > from the userspace. This seems quite limiting in regard to what can be done
>> > with them.
>> >
>> > Are there any plans to allow for creating the inner maps from BPF programs?
>> >
>> > [0] https://stackoverflow.com/a/63391528
>>
>> Did you ask that question or your use case is different?
>> Creating a new map for map_in_map from bpf prog can be implemented.
>> bpf_map_update_elem() is doing memory allocation for map elements.
>> In such a case calling this helper on map_in_map can, in theory, create a new
>> inner map and insert it into the outer map.
>
> No, it wasn't me who asked that question, but it seemed close enough to
> my issue. My use case calls for modifying the syscount example from BCC[1].
>
> The idea is to have an outer map where the keys are PIDs, and inner maps where
> the keys are system call numbers. This would enable tracking the number of
> syscalls made by each process and the makeup of those calls for all processes
> simultaneously.
>
> [1] https://github.com/iovisor/bcc/blob/master/libbpf-tools/syscount.bpf.c

Well, if you just want to count, map-in-map seems a bit overkill? You
could just do:

struct {
  u32 pid;
  u32 syscall;
} map_key;

and use that?

-Toke


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: HASH_OF_MAPS inner map allocation from BPF
  2020-09-07 13:32     ` Toke Høiland-Jørgensen
@ 2020-09-09  9:49       ` Borna Cafuk
  2020-09-09 10:24         ` Toke Høiland-Jørgensen
  0 siblings, 1 reply; 9+ messages in thread
From: Borna Cafuk @ 2020-09-09  9:49 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Alexei Starovoitov, bpf, Luka Perkov, KP Singh

On Mon, Sep 7, 2020 at 3:33 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> Borna Cafuk <borna.cafuk@sartura.hr> writes:
>
> > On Sat, Sep 5, 2020 at 12:47 AM Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> >>
> >> On Fri, Sep 4, 2020 at 7:57 AM Borna Cafuk <borna.cafuk@sartura.hr> wrote:
> >> >
> >> > Hello everyone,
> >> >
> >> > Judging by [0], the inner maps in BPF_MAP_TYPE_HASH_OF_MAPS can only be created
> >> > from the userspace. This seems quite limiting in regard to what can be done
> >> > with them.
> >> >
> >> > Are there any plans to allow for creating the inner maps from BPF programs?
> >> >
> >> > [0] https://stackoverflow.com/a/63391528
> >>
> >> Did you ask that question or your use case is different?
> >> Creating a new map for map_in_map from bpf prog can be implemented.
> >> bpf_map_update_elem() is doing memory allocation for map elements.
> >> In such a case calling this helper on map_in_map can, in theory, create a new
> >> inner map and insert it into the outer map.
> >
> > No, it wasn't me who asked that question, but it seemed close enough to
> > my issue. My use case calls for modifying the syscount example from BCC[1].
> >
> > The idea is to have an outer map where the keys are PIDs, and inner maps where
> > the keys are system call numbers. This would enable tracking the number of
> > syscalls made by each process and the makeup of those calls for all processes
> > simultaneously.
> >
> > [1] https://github.com/iovisor/bcc/blob/master/libbpf-tools/syscount.bpf.c
>
> Well, if you just want to count, map-in-map seems a bit overkill? You
> could just do:
>
> struct {
>   u32 pid;
>   u32 syscall;
> } map_key;
>
> and use that?
>
> -Toke
>

I have considered that, but maps in maps seem better for when I need to get the
data about a single process's syscalls: It requires reading only one of the
inner maps in its entirety. If I have a composite key like that, I don't see
any way, other than:
 * either iterating through all the possible keys for a process
   (i.e. over all syscalls) and looking them up in the map, or
 * iterating over all entries in the map and filtering them.

Looking at it again, the first option does not seem _that_ bad, but just
iterating over one (inner) map would be easier to fit into our use-case.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: HASH_OF_MAPS inner map allocation from BPF
  2020-09-09  9:49       ` Borna Cafuk
@ 2020-09-09 10:24         ` Toke Høiland-Jørgensen
  2020-09-09 10:35           ` KP Singh
  0 siblings, 1 reply; 9+ messages in thread
From: Toke Høiland-Jørgensen @ 2020-09-09 10:24 UTC (permalink / raw)
  To: Borna Cafuk; +Cc: Alexei Starovoitov, bpf, Luka Perkov, KP Singh

Borna Cafuk <borna.cafuk@sartura.hr> writes:

> On Mon, Sep 7, 2020 at 3:33 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>>
>> Borna Cafuk <borna.cafuk@sartura.hr> writes:
>>
>> > On Sat, Sep 5, 2020 at 12:47 AM Alexei Starovoitov
>> > <alexei.starovoitov@gmail.com> wrote:
>> >>
>> >> On Fri, Sep 4, 2020 at 7:57 AM Borna Cafuk <borna.cafuk@sartura.hr> wrote:
>> >> >
>> >> > Hello everyone,
>> >> >
>> >> > Judging by [0], the inner maps in BPF_MAP_TYPE_HASH_OF_MAPS can only be created
>> >> > from the userspace. This seems quite limiting in regard to what can be done
>> >> > with them.
>> >> >
>> >> > Are there any plans to allow for creating the inner maps from BPF programs?
>> >> >
>> >> > [0] https://stackoverflow.com/a/63391528
>> >>
>> >> Did you ask that question or your use case is different?
>> >> Creating a new map for map_in_map from bpf prog can be implemented.
>> >> bpf_map_update_elem() is doing memory allocation for map elements.
>> >> In such a case calling this helper on map_in_map can, in theory, create a new
>> >> inner map and insert it into the outer map.
>> >
>> > No, it wasn't me who asked that question, but it seemed close enough to
>> > my issue. My use case calls for modifying the syscount example from BCC[1].
>> >
>> > The idea is to have an outer map where the keys are PIDs, and inner maps where
>> > the keys are system call numbers. This would enable tracking the number of
>> > syscalls made by each process and the makeup of those calls for all processes
>> > simultaneously.
>> >
>> > [1] https://github.com/iovisor/bcc/blob/master/libbpf-tools/syscount.bpf.c
>>
>> Well, if you just want to count, map-in-map seems a bit overkill? You
>> could just do:
>>
>> struct {
>>   u32 pid;
>>   u32 syscall;
>> } map_key;
>>
>> and use that?
>>
>> -Toke
>>
>
> I have considered that, but maps in maps seem better for when I need to get the
> data about a single process's syscalls: It requires reading only one of the
> inner maps in its entirety. If I have a composite key like that, I don't see
> any way, other than:
>  * either iterating through all the possible keys for a process
>    (i.e. over all syscalls) and looking them up in the map, or
>  * iterating over all entries in the map and filtering them.
>
> Looking at it again, the first option does not seem _that_ bad,

You could even use BPF_MAP_LOOKUP_BATCH to do this in one operation, I
suppose...

> but just iterating over one (inner) map would be easier to fit into
> our use-case.

...but yeah, I see what you mean. Well, maybe BPF local storage per
process would also be a nice fit here?

-Toke


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: HASH_OF_MAPS inner map allocation from BPF
  2020-09-09 10:24         ` Toke Høiland-Jørgensen
@ 2020-09-09 10:35           ` KP Singh
  2020-09-10 10:11             ` Borna Cafuk
  0 siblings, 1 reply; 9+ messages in thread
From: KP Singh @ 2020-09-09 10:35 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Borna Cafuk, Alexei Starovoitov, bpf, Luka Perkov

On Wed, Sep 9, 2020 at 12:24 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> Borna Cafuk <borna.cafuk@sartura.hr> writes:
>
> > On Mon, Sep 7, 2020 at 3:33 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
> >>
> >> Borna Cafuk <borna.cafuk@sartura.hr> writes:
> >>
> >> > On Sat, Sep 5, 2020 at 12:47 AM Alexei Starovoitov
> >> > <alexei.starovoitov@gmail.com> wrote:

[...]

> >> >
> >> > The idea is to have an outer map where the keys are PIDs, and inner maps where
> >> > the keys are system call numbers. This would enable tracking the number of
> >> > syscalls made by each process and the makeup of those calls for all processes
> >> > simultaneously.
> >> >
> >> > [1] https://github.com/iovisor/bcc/blob/master/libbpf-tools/syscount.bpf.c
> >>
> >> Well, if you just want to count, map-in-map seems a bit overkill? You
> >> could just do:
> >>
> >> struct {
> >>   u32 pid;
> >>   u32 syscall;
> >> } map_key;
> >>
> >> and use that?
> >>
> >> -Toke
> >>
> >
> > I have considered that, but maps in maps seem better for when I need to get the
> > data about a single process's syscalls: It requires reading only one of the
> > inner maps in its entirety. If I have a composite key like that, I don't see
> > any way, other than:
> >  * either iterating through all the possible keys for a process
> >    (i.e. over all syscalls) and looking them up in the map, or
> >  * iterating over all entries in the map and filtering them.
> >
> > Looking at it again, the first option does not seem _that_ bad,
>
> You could even use BPF_MAP_LOOKUP_BATCH to do this in one operation, I
> suppose...
>
> > but just iterating over one (inner) map would be easier to fit into
> > our use-case.
>
> ...but yeah, I see what you mean. Well, maybe BPF local storage per
> process would also be a nice fit here?

Yes, task local storage does seem like a good fit and is the next one I was
thinking of implementing.

- KP

>
> -Toke
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: HASH_OF_MAPS inner map allocation from BPF
  2020-09-09 10:35           ` KP Singh
@ 2020-09-10 10:11             ` Borna Cafuk
  0 siblings, 0 replies; 9+ messages in thread
From: Borna Cafuk @ 2020-09-10 10:11 UTC (permalink / raw)
  To: KP Singh
  Cc: Toke Høiland-Jørgensen, Alexei Starovoitov, bpf, Luka Perkov

On Wed, Sep 9, 2020 at 12:36 PM KP Singh <kpsingh@google.com> wrote:
>
> On Wed, Sep 9, 2020 at 12:24 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
> >
> > Borna Cafuk <borna.cafuk@sartura.hr> writes:
> >
> > > On Mon, Sep 7, 2020 at 3:33 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
> > >>
> > >> Borna Cafuk <borna.cafuk@sartura.hr> writes:
> > >>
> > >> > On Sat, Sep 5, 2020 at 12:47 AM Alexei Starovoitov
> > >> > <alexei.starovoitov@gmail.com> wrote:
>
> [...]
>
> > >> >
> > >> > The idea is to have an outer map where the keys are PIDs, and inner maps where
> > >> > the keys are system call numbers. This would enable tracking the number of
> > >> > syscalls made by each process and the makeup of those calls for all processes
> > >> > simultaneously.
> > >> >
> > >> > [1] https://github.com/iovisor/bcc/blob/master/libbpf-tools/syscount.bpf.c
> > >>
> > >> Well, if you just want to count, map-in-map seems a bit overkill? You
> > >> could just do:
> > >>
> > >> struct {
> > >>   u32 pid;
> > >>   u32 syscall;
> > >> } map_key;
> > >>
> > >> and use that?
> > >>
> > >> -Toke
> > >>
> > >
> > > I have considered that, but maps in maps seem better for when I need to get the
> > > data about a single process's syscalls: It requires reading only one of the
> > > inner maps in its entirety. If I have a composite key like that, I don't see
> > > any way, other than:
> > >  * either iterating through all the possible keys for a process
> > >    (i.e. over all syscalls) and looking them up in the map, or
> > >  * iterating over all entries in the map and filtering them.
> > >
> > > Looking at it again, the first option does not seem _that_ bad,
> >
> > You could even use BPF_MAP_LOOKUP_BATCH to do this in one operation, I
> > suppose...
> >
> > > but just iterating over one (inner) map would be easier to fit into
> > > our use-case.
> >
> > ...but yeah, I see what you mean. Well, maybe BPF local storage per
> > process would also be a nice fit here?

Thank you for the insight.

>
> Yes, task local storage does seem like a good fit and is the next one I was
> thinking of implementing.
>
> - KP

I'm looking forward to the patches.

>
> >
> > -Toke
> >

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-09-10 10:11 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-04 14:56 HASH_OF_MAPS inner map allocation from BPF Borna Cafuk
2020-09-04 22:47 ` Alexei Starovoitov
     [not found]   ` <CAFLU3KstRTXs3nwyE8uQY7q9k-sRr1yKCtOQX3gMq3nsxnwHXw@mail.gmail.com>
2020-09-05 14:57     ` KP Singh
2020-09-07 13:13   ` Borna Cafuk
2020-09-07 13:32     ` Toke Høiland-Jørgensen
2020-09-09  9:49       ` Borna Cafuk
2020-09-09 10:24         ` Toke Høiland-Jørgensen
2020-09-09 10:35           ` KP Singh
2020-09-10 10:11             ` Borna Cafuk

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.