public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Felix Maurer <fmaurer@redhat.com>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, horms@kernel.org,
	jkarrenpalo@gmail.com, tglx@linutronix.de, mingo@kernel.org,
	allison.henderson@oracle.com, petrm@nvidia.com,
	antonio@openvpn.net, Yoann Congal <yoann.congal@smile.fr>
Subject: Re: [PATCH net-next v2 6/9] hsr: Implement more robust duplicate discard for HSR
Date: Thu, 29 Jan 2026 17:17:04 +0100	[thread overview]
Message-ID: <aXuIAFJ_m6gMUFFO@thinkpad> (raw)
In-Reply-To: <20260129144348.CIs44m-d@linutronix.de>

On Thu, Jan 29, 2026 at 03:43:48PM +0100, Sebastian Andrzej Siewior wrote:
> On 2026-01-22 15:57:01 [+0100], Felix Maurer wrote:
> …
> > As the problem (we accidentally skip over a sequence number that has not
> > been received but will be received in the future) is similar to PRP, we can
> > apply a similar solution. The duplicate discard algorithm based on the
> > "sparse bitmap" works well for HSR if it is extended to track one bitmap
> > for each port (A, B, master, interlink). To do this, change the sequence
> > number blocks to contain a flexible array member as the last member that
> > can keep chunks for as many bitmaps as we need. This design makes it easy
> > to reuse the same algorithm in a potential PRP RedBox implementation.
>
> I know you just "copy" the logic based on what we have now but…
> Why do we have to track the sequence number for A, B and interlink? The
> 'master' port is what we feed into the stack so this needs to be
> de-duplicated. I am not sure how 'interlink' works so I keep quiet here.
> But A and B? There shouldn't be any duplicates on A and B unless the
> destination node forwards the node. Or do I miss something?
> I'm bringing this up because limiting to one (or two since I am unsure
> about interlink) would save some memory and avoid needless updates. And
> if you have HW-offloading enabled then you shouldn't see any packets
> which are not directed to _this_ node.

About the interlink: that's the interface where you attach devices that
know nothing about HSR, i.e., when we are a RedBox. I consider it very
similar to the master port, it's our responsibility to de-duplicate what
we send out there.

I was thinking about exactly this while working on the patch as well and
I came to each conclusion (A,B are needed vs. are not needed) at least
once. In the end, I think we will need it. It's right that a well
behaving node in the ring should not forward "frames for which the node
is the unique destination" (5.3.2.1). But there could be frames that
have no unique destination in the ring at all: multicast frames or
frames addressed to a non-existing MAC address. We should not forward
such frames either to prevent them from looping forever.

Now, such frames should probably only reach back to us, if we sent them
(either from our stack or from the interlink port). We could track
sequence numbers sent to master and interlink (for de-duplication) and
sent by master and interlink (for loop prevention) for more clarity, but
then we're back at four bitmaps again.

I agree that we can and should optimize the HW-offloaded case. I'd
suggest to do that in a separate patchset, though, partly because I
don't have access to a hardware with HSR offload at the moment.

> …
> > diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
> > index 70b3819e9298..c9bd25e6a7cc 100644
> > --- a/net/hsr/hsr_framereg.c
> > +++ b/net/hsr/hsr_framereg.c
> > @@ -805,6 +774,39 @@ void *hsr_get_next_node(struct hsr_priv *hsr, void *_pos,
> >  	return NULL;
> >  }
> >
> > +/* Fill the last sequence number that has been received from node on if1 by
> > + * finding the last sequence number sent on port B; accordingly get the last
> > + * received sequence number for if2 using sent sequence numbers on port A.
> > + */
> > +static void fill_last_seq_nrs(struct hsr_node *node, u16 *if1_seq, u16 *if2_seq)
> > +{
> > +	struct hsr_seq_block *block;
> > +	unsigned int block_off;
> > +	size_t block_sz;
> > +	u16 seq_bit;
> > +
> > +	spin_lock_bh(&node->seq_out_lock);
> > +
> > +	// Get last inserted block
> > +	block_off = (node->next_block - 1) & (HSR_MAX_SEQ_BLOCKS - 1);
> > +	block_sz = hsr_seq_block_size(node);
> > +	block = node->block_buf + block_off * block_sz;
> > +
> > +	if (!bitmap_empty(block->seq_nrs[HSR_PT_SLAVE_B - 1],
> > +			  HSR_SEQ_BLOCK_SIZE)) {
> > +		seq_bit = find_last_bit(block->seq_nrs[HSR_PT_SLAVE_B - 1],
> > +					HSR_SEQ_BLOCK_SIZE);
> > +		*if1_seq = (block->block_idx << HSR_SEQ_BLOCK_SHIFT) | seq_bit;
> > +	}
> > +	if (!bitmap_empty(block->seq_nrs[HSR_PT_SLAVE_A - 1],
> > +			  HSR_SEQ_BLOCK_SIZE)) {
> > +		seq_bit = find_last_bit(block->seq_nrs[HSR_PT_SLAVE_A - 1],
> > +					HSR_SEQ_BLOCK_SIZE);
> > +		*if2_seq = (block->block_idx << HSR_SEQ_BLOCK_SHIFT) | seq_bit;
> > +	}
> > +	spin_unlock_bh(&node->seq_out_lock);
>
> I know you preserve what is already here but what is this even used for?
> | ip -d link show dev hsr0
>
> does not show these numbers. It shows the sequence number of the hsr0
> interface which I understand.
> But then it is also possible to show the last received sequence number
> of any node on either of the two interfaces?

This is only exposed through the HSR_C_GET_NODE_STATUS netlink command
for the "HSR" (sic!) netlink family. I'm not aware of a userspace tool
that actually shows this data. It's unclear if it is of any real use.

I assume that the two sequence numbers are reported because they would
in theory allow to detect a broken ring: if one of the numbers stops
increasing or the numbers generally diverge, some link in the ring is
broken. If we have traffic from multiple nodes, we could even detect
where the ring is broken. That's likely also the reason for the weird
cross-assinment of B->1, A->2. What we send out on B has to have arrived
on port A resp. 1 before.

We can discuss removing this stuff in the future, but I'd prefer not to
touch userspace at this time.

> > +}
> > +
> >  int hsr_get_node_data(struct hsr_priv *hsr,
> >  		      const unsigned char *addr,
> >  		      unsigned char addr_b[ETH_ALEN],
> …
> > --- a/net/hsr/hsr_framereg.h
> > +++ b/net/hsr/hsr_framereg.h
> > @@ -82,15 +82,18 @@ int prp_register_frame_out(struct hsr_port *port, struct hsr_frame_info *frame);
> >  #define hsr_seq_block_index(sequence_nr) ((sequence_nr) >> HSR_SEQ_BLOCK_SHIFT)
> >  #define hsr_seq_block_bit(sequence_nr) ((sequence_nr) & HSR_SEQ_BLOCK_MASK)
> >
> > +#define DECLARE_BITMAP_FLEX_ARRAY(name, bits) \
> > +	unsigned long name[][BITS_TO_LONGS(bits)]
> > +
> >  struct hsr_seq_block {
> >  	unsigned long		time;
> >  	u16			block_idx;
> > -	DECLARE_BITMAP(seq_nrs, HSR_SEQ_BLOCK_SIZE);
> > +	DECLARE_BITMAP_FLEX_ARRAY(seq_nrs, HSR_SEQ_BLOCK_SIZE);
>
> is there a story behind DECLARE_BITMAP_FLEX_ARRAY()? We have just this
> one user.

I've added it this way to make it obvious that almost all of it is the
same as DECLARE_BITMAP(). But probably it's better to get rid of the
macro, add the definition directly to the struct, and maybe add a
comment that it's supposed to be similar to what DECLARE_BITMAP()
produces. What do you think?

Thanks for your comments,
   Felix


> >  };
>
> Sebastian


  reply	other threads:[~2026-01-29 16:17 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-22 14:56 [PATCH net-next v2 0/9] hsr: Implement more robust duplicate discard algorithm Felix Maurer
2026-01-22 14:56 ` [PATCH net-next v2 1/9] selftests: hsr: Add ping test for PRP Felix Maurer
2026-01-29 11:05   ` Sebastian Andrzej Siewior
2026-01-29 13:31     ` Felix Maurer
2026-01-29 15:21       ` Sebastian Andrzej Siewior
2026-01-29 17:44         ` Felix Maurer
2026-02-02 11:51           ` Felix Maurer
2026-02-02 15:55             ` Sebastian Andrzej Siewior
2026-02-03 10:12               ` Felix Maurer
2026-02-03 11:55                 ` Sebastian Andrzej Siewior
2026-02-03 12:23                   ` Felix Maurer
2026-02-03 13:47                     ` Sebastian Andrzej Siewior
2026-02-03 15:07                       ` Felix Maurer
2026-01-22 14:56 ` [PATCH net-next v2 2/9] selftests: hsr: Check duplicates on HSR with VLAN Felix Maurer
2026-01-22 14:56 ` [PATCH net-next v2 3/9] selftests: hsr: Add tests for faulty links Felix Maurer
2026-01-22 14:56 ` [PATCH net-next v2 4/9] hsr: Implement more robust duplicate discard for PRP Felix Maurer
2026-01-28 16:38   ` Simon Horman
2026-01-28 18:37     ` Felix Maurer
2026-02-02 16:57       ` Sebastian Andrzej Siewior
2026-02-03 10:23         ` Felix Maurer
2026-02-03 11:57           ` Sebastian Andrzej Siewior
2026-02-03 12:42             ` Felix Maurer
2026-02-03 13:49               ` Sebastian Andrzej Siewior
2026-02-03 15:11                 ` Felix Maurer
2026-01-29 13:29   ` Sebastian Andrzej Siewior
2026-01-29 15:30     ` Felix Maurer
2026-02-02  8:47   ` Steffen Lindner
2026-01-22 14:57 ` [PATCH net-next v2 5/9] selftests: hsr: Add tests for more link faults with PRP Felix Maurer
2026-01-29 13:32   ` Sebastian Andrzej Siewior
2026-02-02 11:30     ` Felix Maurer
2026-02-02 16:45       ` Sebastian Andrzej Siewior
2026-02-03 12:09         ` Felix Maurer
2026-02-03 14:49           ` Sebastian Andrzej Siewior
2026-02-03 15:32             ` Felix Maurer
2026-01-22 14:57 ` [PATCH net-next v2 6/9] hsr: Implement more robust duplicate discard for HSR Felix Maurer
2026-01-29 14:43   ` Sebastian Andrzej Siewior
2026-01-29 16:17     ` Felix Maurer [this message]
2026-01-29 18:01       ` Felix Maurer
2026-01-30 10:34         ` Felix Maurer
2026-02-02 17:53           ` Sebastian Andrzej Siewior
2026-02-03 11:49             ` Felix Maurer
2026-02-03 12:08               ` Sebastian Andrzej Siewior
2026-02-02 17:11       ` Sebastian Andrzej Siewior
2026-02-03 11:08         ` Felix Maurer
2026-02-03 12:09           ` Sebastian Andrzej Siewior
2026-01-22 14:57 ` [PATCH net-next v2 7/9] selftests: hsr: Add more link fault tests " Felix Maurer
2026-01-22 14:57 ` [PATCH net-next v2 8/9] hsr: Update PRP duplicate discard KUnit test for new algorithm Felix Maurer
2026-01-29 15:12   ` Sebastian Andrzej Siewior
2026-01-29 16:19     ` Felix Maurer
2026-01-22 14:57 ` [PATCH net-next v2 9/9] MAINTAINERS: Assign hsr selftests to HSR Felix Maurer
2026-01-22 17:24 ` [PATCH net-next v2 0/9] hsr: Implement more robust duplicate discard algorithm Sebastian Andrzej Siewior
2026-01-23  1:35 ` Jakub Kicinski
2026-01-26  9:28   ` Felix Maurer
2026-01-29 15:29     ` Sebastian Andrzej Siewior
2026-01-29 16:29       ` Felix Maurer

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=aXuIAFJ_m6gMUFFO@thinkpad \
    --to=fmaurer@redhat.com \
    --cc=allison.henderson@oracle.com \
    --cc=antonio@openvpn.net \
    --cc=bigeasy@linutronix.de \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=jkarrenpalo@gmail.com \
    --cc=kuba@kernel.org \
    --cc=mingo@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=petrm@nvidia.com \
    --cc=tglx@linutronix.de \
    --cc=yoann.congal@smile.fr \
    /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