On Wed, Apr 28, 2021 at 12:10:31AM +0200, Alexandr Nedvedicky wrote:
> Hello,
>
> On Tue, Apr 27, 2021 at 11:45:19PM +0200, Alexander Bluhm wrote:
> > On Sun, Apr 25, 2021 at 06:08:17PM +1000, Jonathan Matthew wrote:
> > > On Sun, Apr 25, 2021 at 09:44:16AM +0200, Alexandr Nedvedicky wrote:
> > > This already exists, it's called mq_delist()
> >
> > Here is the diff with mq_delist().
> >
> > > We'd need some other way to do the 'mbuf is back in queue' detection,
> > > but I agree this seems like a sensible thing to do.
> >
> > This part is ugly as before. I have put a printf in the discard
> > case it and I never hit it. Any idea why we need this and how to
> > fix it?
> >
> > ok?
> >
> > bluhm
> >
> > Index: netinet/if_ether.c
> > ===================================================================
> > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/if_ether.c,v
> > retrieving revision 1.246
> > diff -u -p -r1.246 if_ether.c
> > --- netinet/if_ether.c 26 Apr 2021 07:55:16 -0000 1.246
> > +++ netinet/if_ether.c 27 Apr 2021 21:02:27 -0000
> > @@ -594,7 +594,9 @@ arpcache(struct ifnet *ifp, struct ether
> > struct in_addr *spa = (struct in_addr *)ea->arp_spa;
> > char addr[INET_ADDRSTRLEN];
> > struct ifnet *rifp;
> > + struct mbuf_list ml;
> > struct mbuf *m;
> > + unsigned int len;
> > int changed = 0;
> >
> > KERNEL_ASSERT_LOCKED();
> > @@ -666,21 +668,17 @@ arpcache(struct ifnet *ifp, struct ether
> >
> > la->la_asked = 0;
> > la->la_refreshed = 0;
> > - while ((m = mq_dequeue(&la->la_mq)) != NULL) {
> > - unsigned int len;
> > -
> > - atomic_dec_int(&la_hold_total);
> > - len = mq_len(&la->la_mq);
> > -
> > + mq_delist(&la->la_mq, &ml);
> > + len = ml_len(&ml);
> > + while ((m = ml_dequeue(&ml)) != NULL) {
> > ifp->if_output(ifp, m, rt_key(rt), rt);
> > -
> > - /* XXXSMP we discard if other CPU enqueues */
> > - if (mq_len(&la->la_mq) > len) {
> > - /* mbuf is back in queue. Discard. */
> > - atomic_sub_int(&la_hold_total, mq_purge(&la->la_mq));
> > - break;
> > - }
> > }
>
> > + /* XXXSMP we discard if other CPU enqueues */
> > + if (mq_len(&la->la_mq) > 0) {
> > + /* mbuf is back in queue. Discard. */
> > + atomic_sub_int(&la_hold_total, len + mq_purge(&la->la_mq));
> > + } else
> > + atomic_sub_int(&la_hold_total, len);
> >
>
> I think /* XXXSMP ... */ code-chunk is no longer needed. I think your
> change, which introduces ml_dequeue(), turns that into an useless
> artifact.
>
> If I understand old code right this extra check tries to make sure
> the while() loop completes. I assume ifp->if_output() calls
> ether_output(),
> which in turn calls ether_encap() -> ether_resolve(). If ether_resolve()
> fails to find ARP entry (for whatever reason, perhaps explicit 'arp -d -a'
> or interface down), the packet is inserted back to la->la_mq. This would
> keep the while loop spinning.
>
The code not only breaks loop but also cleans the queue. Should this be
kept?
> using ml_dequeue() solves that problem, because the while() loop now
> consumes a private list of packets, which can not grow. It's granted
> the loop will finish.
>
> So I would just delete those lines.
>
>
> thanks and
> regards
> sashan
>
>
> > return (0);
> > }
>