All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Olsa <olsajiri@gmail.com>
To: Dave Marchevsky <davemarchevsky@fb.com>
Cc: bpf@vger.kernel.org, Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@kernel.org>,
	Kernel Team <kernel-team@fb.com>
Subject: Re: [PATCH v1 bpf-next 3/4] btf: Descend into structs and arrays during special field search
Date: Mon, 30 Oct 2023 13:56:32 +0100	[thread overview]
Message-ID: <ZT+oAHR3YB93H7XQ@krava> (raw)
In-Reply-To: <20231023220030.2556229-4-davemarchevsky@fb.com>

On Mon, Oct 23, 2023 at 03:00:29PM -0700, Dave Marchevsky wrote:

SNIP

> -			ret = btf_maybe_find_kptr(btf, member_type, off, srch);
> +			ret = btf_find_aggregate_field(btf, member_type, srch,
> +						       struct_field_off + off,
> +						       rec);
>  			if (ret < 0)
>  				return ret;
>  			continue;
> @@ -3541,15 +3587,17 @@ static int btf_find_struct_field(const struct btf *btf,
>  		case BPF_LIST_NODE:
>  		case BPF_RB_NODE:
>  		case BPF_REFCOUNT:
> -			ret = btf_find_struct(btf, member_type, off, sz, field_type,
> -					      srch);
> +			ret = btf_find_struct(btf, member_type,
> +					      struct_field_off + off,
> +					      sz, field_type, srch);
>  			if (ret < 0)
>  				return ret;
>  			break;
>  		case BPF_LIST_HEAD:
>  		case BPF_RB_ROOT:
>  			ret = btf_find_graph_root(btf, t, member_type,
> -						  i, off, sz, srch, field_type);
> +						  i, struct_field_off + off, sz,
> +						  srch, field_type);
>  			if (ret < 0)
>  				return ret;
>  			break;
> @@ -3566,6 +3614,82 @@ static int btf_find_struct_field(const struct btf *btf,
>  	return srch->idx;
>  }
>  
> +static int btf_flatten_array_field(const struct btf *btf,
> +				   const struct btf_type *t,
> +				   struct btf_field_info_search *srch,
> +				   int array_field_off, int rec)
> +{
> +	int ret, start_idx, elem_field_cnt;
> +	const struct btf_type *elem_type;
> +	struct btf_field_info *info;
> +	u32 i, j, off, nelems;
> +
> +	if (!btf_type_is_array(t))
> +		return -EINVAL;

seems this check is not needed, it's called only for
btf_type_is_array(t)

> +	nelems = __multi_dim_elem_type_nelems(btf, t, &elem_type);
> +	if (!nelems || !__btf_type_is_struct(elem_type))
> +		return srch->idx;
> +
> +	start_idx = srch->idx;
> +	ret = btf_find_struct_field(btf, elem_type, srch, array_field_off + off, rec);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* No btf_field_info's added */
> +	if (srch->idx == start_idx)
> +		return srch->idx;
> +
> +	elem_field_cnt = srch->idx - start_idx;
> +	info = __next_field_infos(srch, elem_field_cnt * (nelems - 1));
> +	if (IS_ERR_OR_NULL(info))
> +		return PTR_ERR(info);
> +
> +	/* Array elems after the first can copy first elem's btf_field_infos
> +	 * and adjust offset
> +	 */
> +	for (i = 1; i < nelems; i++) {
> +		memcpy(info, &srch->infos[start_idx],
> +		       elem_field_cnt * sizeof(struct btf_field_info));
> +		for (j = 0; j < elem_field_cnt; j++) {
> +			info->off += (i * elem_type->size);
> +			info++;
> +		}
> +	}
> +	return srch->idx;
> +}
> +
> +static int btf_find_aggregate_field(const struct btf *btf,
> +				    const struct btf_type *t,
> +				    struct btf_field_info_search *srch,
> +				    int field_off, int rec)
> +{
> +	u32 orig_field_mask;
> +	int ret;
> +
> +	/* Dig up to 4 levels deep */
> +	if (rec >= 4)
> +		return -E2BIG;

do we need to fails in here? should we just stop descend?
and continue the search in upper layers

> +
> +	orig_field_mask = srch->field_mask;
> +	srch->field_mask &= BPF_KPTR;
> +
> +	if (!srch->field_mask) {
> +		ret = 0;
> +		goto reset_field_mask;
> +	}

could this be just

	if (!(srch->field_mask & BPF_KPTR))
		return 0;

but I don't understand why there's the BPF_KPTR restriction in here


jirka

> +
> +	if (__btf_type_is_struct(t))
> +		ret = btf_find_struct_field(btf, t, srch, field_off, rec + 1);
> +	else if (btf_type_is_array(t))
> +		ret = btf_flatten_array_field(btf, t, srch, field_off, rec + 1);
> +	else
> +		ret = -EINVAL;
> +
> +reset_field_mask:
> +	srch->field_mask = orig_field_mask;
> +	return ret;
> +}
> +
>  static int __datasec_vsi_check_align_sz(const struct btf_var_secinfo *vsi,
>  					enum btf_field_type field_type,
>  					u32 expected_sz)
> @@ -3605,10 +3729,19 @@ static int btf_find_datasec_var(const struct btf *btf, const struct btf_type *t,
>  			 * btf_maybe_find_kptr will find actual kptr type
>  			 */
>  			sz = btf_field_type_size(BPF_KPTR_REF);
> -			if (__datasec_vsi_check_align_sz(vsi, BPF_KPTR_REF, sz))
> +			if (srch->field_mask & BPF_KPTR &&
> +			    !__datasec_vsi_check_align_sz(vsi, BPF_KPTR_REF, sz)) {
> +				ret = btf_maybe_find_kptr(btf, var_type, off, srch);
> +				if (ret < 0)
> +					return ret;
> +				if (ret == BTF_FIELD_FOUND)
> +					continue;
> +			}
> +
> +			if (!(btf_type_is_array(var_type) || __btf_type_is_struct(var_type)))
>  				continue;
>  
> -			ret = btf_maybe_find_kptr(btf, var_type, off, srch);
> +			ret = btf_find_aggregate_field(btf, var_type, srch, off, 0);
>  			if (ret < 0)
>  				return ret;
>  			continue;
> @@ -3655,7 +3788,7 @@ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
>  			  struct btf_field_info_search *srch)
>  {
>  	if (__btf_type_is_struct(t))
> -		return btf_find_struct_field(btf, t, srch);
> +		return btf_find_struct_field(btf, t, srch, 0, 0);
>  	else if (btf_type_is_datasec(t))
>  		return btf_find_datasec_var(btf, t, srch);
>  	return -EINVAL;
> -- 
> 2.34.1
> 
> 

  parent reply	other threads:[~2023-10-30 12:56 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-23 22:00 [PATCH v1 bpf-next 0/4] Descend into struct, array types when searching for fields Dave Marchevsky
2023-10-23 22:00 ` [PATCH v1 bpf-next 1/4] bpf: Fix btf_get_field_type to fail for multiple bpf_refcount fields Dave Marchevsky
2023-10-30 17:56   ` Yonghong Song
2023-11-01 21:56   ` Andrii Nakryiko
2023-10-23 22:00 ` [PATCH v1 bpf-next 2/4] bpf: Refactor btf_find_field with btf_field_info_search Dave Marchevsky
2023-10-28 14:52   ` Jiri Olsa
2023-10-30 19:31   ` Yonghong Song
2023-10-30 19:56     ` Yonghong Song
2023-11-01 21:56   ` Andrii Nakryiko
2023-10-23 22:00 ` [PATCH v1 bpf-next 3/4] btf: Descend into structs and arrays during special field search Dave Marchevsky
2023-10-26  1:24   ` kernel test robot
2023-10-30 12:56   ` Jiri Olsa [this message]
2023-10-30 20:56   ` Yonghong Song
2023-11-01 21:56   ` Andrii Nakryiko
2023-10-23 22:00 ` [PATCH v1 bpf-next 4/4] selftests/bpf: Add tests exercising aggregate type BTF " Dave Marchevsky
2023-10-23 23:32   ` kernel test robot
2023-10-30 21:10   ` Yonghong Song
2023-11-01 21:56   ` Andrii Nakryiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZT+oAHR3YB93H7XQ@krava \
    --to=olsajiri@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davemarchevsky@fb.com \
    --cc=kernel-team@fb.com \
    --cc=martin.lau@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.