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); return (0); }