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.
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);
> }