Re: [PATCH bpf-next v1 7/8] libbpf: sync progs autoload with maps autocreate for struct_ops maps

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2024-02-27 at 16:12 -0800, Kui-Feng Lee wrote:
[...]

> It only has to scan once with an additional flag.
> The value of the autoload of a prog should be
> true if its autoload_user_set is false and autocreate of any one of
> struct_ops maps pointing to the prog is true.
> 
> Let's say the flag is autoload_autocreate.
> In bpf_map__init_kern_struct_ops(), it has to check
> prog->autoload_user_set, and do prog->autoload |= map->autocreate if
> prog->autoload_user_set is false and autoload_autocreate is true. Do 
> prog->autoload = map->autocreate if autoload_autocreate is false I think 
> it is enough, right?
> 
> if (!prog->autoload_user_set) {
>      if (!prog->autoload_autocreate)
>          prog->autoload = map->autocreate;
>      else
>          prog->autoload |= map->autocreate;
>      prog->autoload_autocreate = true;
> }

Since the full thing is moved to load phase I was hoping to make do
w/o changes to struct bpf_program. To have it more contained.
E.g. the code below apperas to work (needs more testing):

--- 8< -------------------------------------

static int bpf_object__adjust_struct_ops_autoload(struct bpf_object *obj)
{
	struct bpf_program *prog;
	struct bpf_map *map;
	int i, j, k, vlen;
	struct {
		__u8 autoload:1;
		/* only change autoload for programs that are
		 * referenced from some struct_ops maps
		 */
		__u8 used:1;
	} *refs;

	refs = calloc(obj->nr_programs, sizeof(refs[0]));
	if (!refs)
		return -ENOMEM;

	for (i = 0; i < obj->nr_maps; i++) {
		map = &obj->maps[i];
		if (!bpf_map__is_struct_ops(map))
			continue;

		vlen = btf_vlen(map->st_ops->type);
		for (j = 0; j < vlen; ++j) {
			prog = map->st_ops->progs[j];
			if (!prog)
				continue;

			k = prog - obj->programs;
			refs[k].used = true;
			refs[k].autoload |= map->autocreate;
		}
	}

	for (i = 0; i < obj->nr_programs; ++i) {
		prog = &obj->programs[i];
		if (prog->autoload_user_set || !refs[i].used)
			continue;

		prog->autoload = refs[i].autoload;
	}

	free(refs);
	return 0;
}

------------------------------------- >8 ---





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux