public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
From: Martin KaFai Lau <martin.lau@linux.dev>
To: Aditi Ghag <aditi.ghag@isovalent.com>
Cc: kafai@fb.com, sdf@google.com, edumazet@google.com,
	Martin KaFai Lau <martin.lau@kernel.org>,
	bpf@vger.kernel.org
Subject: Re: [PATCH v5 bpf-next 4/7] bpf: udp: Implement batching for sockets iterator
Date: Fri, 31 Mar 2023 14:08:35 -0700	[thread overview]
Message-ID: <acdafa2f-b127-5a5a-84f7-0a046e1ce0fa@linux.dev> (raw)
In-Reply-To: <20230330151758.531170-5-aditi.ghag@isovalent.com>

On 3/30/23 8:17 AM, Aditi Ghag wrote:
> +static int bpf_iter_udp_realloc_batch(struct bpf_udp_iter_state *iter,
> +				      unsigned int new_batch_sz);
>   
>   static inline bool seq_sk_match(struct seq_file *seq, const struct sock *sk)
>   {
> @@ -3151,6 +3163,149 @@ static inline bool seq_sk_match(struct seq_file *seq, const struct sock *sk)
>   		net_eq(sock_net(sk), seq_file_net(seq)));
>   }
>   
> +static struct sock *bpf_iter_udp_batch(struct seq_file *seq)
> +{
> +	struct bpf_udp_iter_state *iter = seq->private;
> +	struct udp_iter_state *state = &iter->state;
> +	struct net *net = seq_file_net(seq);
> +	struct sock *first_sk = NULL;
> +	struct udp_seq_afinfo afinfo;
> +	struct udp_table *udptable;
> +	unsigned int batch_sks = 0;
> +	bool resized = false;
> +	struct sock *sk;
> +	int offset = 0;
> +	int new_offset;
> +
> +	/* The current batch is done, so advance the bucket. */
> +	if (iter->st_bucket_done) {
> +		state->bucket++;
> +		iter->offset = 0;
> +	}
> +
> +	afinfo.family = AF_UNSPEC;
> +	afinfo.udp_table = NULL;
> +	udptable = udp_get_table_afinfo(&afinfo, net);
> +
> +	if (state->bucket > udptable->mask) {

This test looks unnecessary. The for-loop below should take care of this case?

> +		state->bucket = 0;

Reset state->bucket here looks suspicious (or at least unnecessary) also. The 
iterator cannot restart from the beginning. or I am missing something here? This 
at least requires a comment if it is really needed.

> +		iter->offset = 0;
> +		return NULL;
> +	}
> +
> +again:
> +	/* New batch for the next bucket.
> +	 * Iterate over the hash table to find a bucket with sockets matching
> +	 * the iterator attributes, and return the first matching socket from
> +	 * the bucket. The remaining matched sockets from the bucket are batched
> +	 * before releasing the bucket lock. This allows BPF programs that are
> +	 * called in seq_show to acquire the bucket lock if needed.
> +	 */
> +	iter->cur_sk = 0;
> +	iter->end_sk = 0;
> +	iter->st_bucket_done = false;
> +	first_sk = NULL;
> +	batch_sks = 0;
> +	offset = iter->offset;
> +
> +	for (; state->bucket <= udptable->mask; state->bucket++) {
> +		struct udp_hslot *hslot2 = &udptable->hash2[state->bucket];
> +
> +		if (hlist_empty(&hslot2->head)) {
> +			offset = 0;
> +			continue;
> +		}
> +		new_offset = offset;
> +
> +		spin_lock_bh(&hslot2->lock);
> +		udp_portaddr_for_each_entry(sk, &hslot2->head) {
> +			if (seq_sk_match(seq, sk)) {
> +				/* Resume from the last iterated socket at the
> +				 * offset in the bucket before iterator was stopped.
> +				 */
> +				if (offset) {
> +					--offset;
> +					continue;
> +				}
> +				if (!first_sk)
> +					first_sk = sk;
> +				if (iter->end_sk < iter->max_sk) {
> +					sock_hold(sk);
> +					iter->batch[iter->end_sk++] = sk;
> +				}
> +				batch_sks++;
> +				new_offset++;
> +			}
> +		}
> +		spin_unlock_bh(&hslot2->lock);
> +
> +		if (first_sk)
> +			break;
> +
> +		/* Reset the current bucket's offset before moving to the next bucket. */
> +		offset = 0;
> +	}
> +
> +	/* All done: no batch made. */
> +	if (!first_sk)

Testing !iter->end_sk should be the same?

> +		goto ret;
> +
> +	if (iter->end_sk == batch_sks) {
> +		/* Batching is done for the current bucket; return the first
> +		 * socket to be iterated from the batch.
> +		 */
> +		iter->st_bucket_done = true;
> +		goto ret;
> +	}
> +	if (!resized && !bpf_iter_udp_realloc_batch(iter, batch_sks * 3 / 2)) {
> +		resized = true;
> +		/* Go back to the previous bucket to resize its batch. */
> +		state->bucket--;
> +		goto again;
> +	}
> +ret:
> +	iter->offset = new_offset;

hmm... updating iter->offset looks not right and,
does it need a new_offset?

afaict, either

a) it can resume at the old bucket. In this case, the iter->offset should not 
change.

or

b) it moved to the next bucket and iter->offset should be 0.

> +	return first_sk;

&iter->batch[0] is the first_sk. 'first_sk' variable is not needed then.


  reply	other threads:[~2023-03-31 21:08 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-30 15:17 [PATCH v5 bpf-next 0/7] bpf: Add socket destroy capability Aditi Ghag
2023-03-30 15:17 ` [PATCH v5 bpf-next 1/7] bpf: tcp: Avoid taking fast sock lock in iterator Aditi Ghag
2023-03-30 15:17 ` [PATCH v5 bpf-next 2/7] udp: seq_file: Remove bpf_seq_afinfo from udp_iter_state Aditi Ghag
2023-03-30 17:35   ` Martin KaFai Lau
2023-03-30 15:17 ` [PATCH v5 bpf-next 3/7] udp: seq_file: Helper function to match socket attributes Aditi Ghag
2023-03-30 18:40   ` kernel test robot
2023-03-30 18:51   ` kernel test robot
2023-03-31  2:52   ` kernel test robot
2023-03-31 20:09   ` Martin KaFai Lau
2023-04-03 15:27     ` Aditi Ghag
2023-04-02  6:18   ` kernel test robot
2023-03-30 15:17 ` [PATCH v5 bpf-next 4/7] bpf: udp: Implement batching for sockets iterator Aditi Ghag
2023-03-31 21:08   ` Martin KaFai Lau [this message]
2023-04-03 15:54     ` Aditi Ghag
2023-04-03 19:20       ` Martin KaFai Lau
2023-03-30 15:17 ` [PATCH v5 bpf-next 5/7] bpf: Add bpf_sock_destroy kfunc Aditi Ghag
2023-03-31 22:24   ` Martin KaFai Lau
2023-04-04  6:09     ` [RFC PATCH bpf-next] bpf: Add a kfunc filter function to 'struct btf_kfunc_id_set' Martin KaFai Lau
2023-04-05 15:05       ` Aditi Ghag
2023-04-05 17:26         ` Martin KaFai Lau
2023-04-10 23:05       ` Aditi Ghag
2023-04-12 15:21         ` Aditi Ghag
2023-03-30 15:17 ` [PATCH v5 bpf-next 6/7] selftests/bpf: Add helper to get port using getsockname Aditi Ghag
2023-03-30 18:41   ` Stanislav Fomichev
2023-03-31 21:37     ` Martin KaFai Lau
2023-03-30 15:17 ` [PATCH v5 bpf-next 7/7] selftests/bpf: Test bpf_sock_destroy Aditi Ghag
2023-03-30 18:46   ` Stanislav Fomichev
2023-03-31 22:32     ` Martin KaFai Lau
2023-04-03 15:55       ` Aditi Ghag
2023-04-03 17:35         ` Martin KaFai Lau
2023-04-04  0:15           ` Aditi Ghag
2023-04-04  1:41             ` Martin KaFai Lau
2023-04-04 14:24               ` Aditi Ghag

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=acdafa2f-b127-5a5a-84f7-0a046e1ce0fa@linux.dev \
    --to=martin.lau@linux.dev \
    --cc=aditi.ghag@isovalent.com \
    --cc=bpf@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=kafai@fb.com \
    --cc=martin.lau@kernel.org \
    --cc=sdf@google.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox