[Differential] D8637: buf_ring.h: fix memory order issues.

2016-11-25 Thread oleg (Oleg Bulyzhin)
oleg created this revision.
oleg added reviewers: kmacy, alc, kib.
oleg added a subscriber: freebsd-net-list.

REVISION SUMMARY
  Properly use acqure/release atomics.

REVISION DETAIL
  https://reviews.freebsd.org/D8637

AFFECTED FILES
  sys/sys/buf_ring.h

EMAIL PREFERENCES
  https://reviews.freebsd.org/settings/panel/emailpreferences/

To: oleg, kmacy, alc, kib
Cc: freebsd-net-list
diff --git a/sys/sys/buf_ring.h b/sys/sys/buf_ring.h
--- a/sys/sys/buf_ring.h
+++ b/sys/sys/buf_ring.h
@@ -75,35 +75,29 @@
 #endif	
 	critical_enter();
 	do {
+		cons_tail = atomic_load_acq_32(&br->br_cons_tail);
 		prod_head = br->br_prod_head;
 		prod_next = (prod_head + 1) & br->br_prod_mask;
-		cons_tail = br->br_cons_tail;
 
 		if (prod_next == cons_tail) {
-			rmb();
-			if (prod_head == br->br_prod_head &&
-			cons_tail == br->br_cons_tail) {
-br->br_drops++;
-critical_exit();
-return (ENOBUFS);
-			}
-			continue;
+			br->br_drops++;
+			critical_exit();
+			return (ENOBUFS);
 		}
-	} while (!atomic_cmpset_acq_int(&br->br_prod_head, prod_head, prod_next));
+	} while (!atomic_cmpset_32(&br->br_prod_head, prod_head, prod_next));
 #ifdef DEBUG_BUFRING
 	if (br->br_ring[prod_head] != NULL)
 		panic("dangling value in enqueue");
 #endif	
 	br->br_ring[prod_head] = buf;
-
 	/*
 	 * If there are other enqueues in progress
 	 * that preceded us, we need to wait for them
 	 * to complete 
 	 */   
 	while (br->br_prod_tail != prod_head)
 		cpu_spinwait();
-	atomic_store_rel_int(&br->br_prod_tail, prod_next);
+	atomic_store_rel_32(&br->br_prod_tail, prod_next);
 	critical_exit();
 	return (0);
 }
@@ -115,19 +109,21 @@
 static __inline void *
 buf_ring_dequeue_mc(struct buf_ring *br)
 {
-	uint32_t cons_head, cons_next;
+	uint32_t cons_head, cons_next, prod_tail;
 	void *buf;
 
 	critical_enter();
 	do {
+		prod_tail = atomic_load_acq_32(&br->br_prod_tail);
 		cons_head = br->br_cons_head;
-		cons_next = (cons_head + 1) & br->br_cons_mask;
 
-		if (cons_head == br->br_prod_tail) {
+		if (cons_head == prod_tail) {
 			critical_exit();
 			return (NULL);
 		}
-	} while (!atomic_cmpset_acq_int(&br->br_cons_head, cons_head, cons_next));
+
+		cons_next = (cons_head + 1) & br->br_cons_mask;
+	} while (!atomic_cmpset_32(&br->br_cons_head, cons_head, cons_next));
 
 	buf = br->br_ring[cons_head];
 #ifdef DEBUG_BUFRING
@@ -140,10 +136,8 @@
 	 */   
 	while (br->br_cons_tail != cons_head)
 		cpu_spinwait();
-
-	atomic_store_rel_int(&br->br_cons_tail, cons_next);
+	atomic_store_rel_32(&br->br_cons_tail, cons_next);
 	critical_exit();
-
 	return (buf);
 }
 
@@ -155,62 +149,29 @@
 static __inline void *
 buf_ring_dequeue_sc(struct buf_ring *br)
 {
-	uint32_t cons_head, cons_next;
+	uint32_t cons_head, cons_next, prod_tail;
 #ifdef PREFETCH_DEFINED
 	uint32_t cons_next_next;
 #endif
-	uint32_t prod_tail;
 	void *buf;
 
-	/*
-	 * This is a workaround to allow using buf_ring on ARM and ARM64.
-	 * ARM64TODO: Fix buf_ring in a generic way.
-	 * REMARKS: It is suspected that br_cons_head does not require
-	 *   load_acq operation, but this change was extensively tested
-	 *   and confirmed it's working. To be reviewed once again in
-	 *   FreeBSD-12.
-	 *
-	 * Preventing following situation:
-
-	 * Core(0) - buf_ring_enqueue()   Core(1) - buf_ring_dequeue_sc()
-	 * -   --
-	 *
-	 *cons_head = br->br_cons_head;
-	 * atomic_cmpset_acq_32(&br->br_prod_head, ...));
-	 *buf = br->br_ring[cons_head]; >
-	 * br->br_ring[prod_head] = buf;
-	 * atomic_store_rel_32(&br->br_prod_tail, ...);
-	 *prod_tail = br->br_prod_tail;
-	 *if (cons_head == prod_tail) 
-	 *return (NULL);
-	 *`	
-	 *
-	 * <1> Load (on core 1) from br->br_ring[cons_head] can be reordered (speculative readed) by CPU.
-	 */	
-#if defined(__arm__) || defined(__aarch64__)
-	cons_head = atomic_load_acq_32(&br->br_cons_head);
-#else
-	cons_head = br->br_cons_head;
-#endif
 	prod_tail = atomic_load_acq_32(&br->br_prod_tail);
-	
-	cons_next = (cons_head + 1) & br->br_cons_mask;
-#ifdef PREFETCH_DEFINED
-	cons_next_next = (cons_head + 2) & br->br_cons_mask;
-#endif
+	cons_head = br->br_cons_head;
 	
 	if (cons_head == prod_tail) 
 		return (NULL);
 
-#ifdef PREFETCH_DEFINED	
+	cons_next = (cons_head + 1) & br->br_cons_mask;
+#ifdef PREFETCH_DEFINED
 	if (cons_next != prod_tail) {		
 		prefetch(br->br_ring[cons_next]);
+		cons_next_next = (cons_head

FLOWTABLE aka TCP route caching panic

2016-11-25 Thread Jakub Palider
Hi,
I have found that last month (19 Oct) the problem appeared on this list,
and to my experience it persists, both on VM and bare metal installation
(HEAD from yesterday). I looks that enabling FLOWTABLE option is the only
source of this fault happening. It appears on our setup in 80% cases within
one hour from boot up.
>From our debugging, it is caused by lock on DESTROYED lock. Did you find a
solution to this problem?

Regards,
Jakub
___
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"


[Bug 213410] [carp] service netif restart causes hang only when carp is enabled

2016-11-25 Thread bugzilla-noreply
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=213410

Kristof Provost  changed:

   What|Removed |Added

 CC||k...@freebsd.org

--- Comment #1 from Kristof Provost  ---
I’ve had a very quick look, and at first glance it seems like an overly strict
KASSERT() more than anything else.
Basically, during service netif restart the scripts try to set up carp on an
address that’s already got it configured. That runs into the assert and panics
the box (or actually panics later on if INVARIANTS is not set).

Simply replacing the KASSERT with a check (and returning errors) prevents the
panic.
I don’t have a carp test setup, but this should make things a lot better
already.

Can you check if this works for you?

diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index
7855af2..ea27f0a 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1804,7 +1804,8 @@ carp_attach(struct ifaddr *ifa, int vhid)
struct carp_softc *sc;
int index, error;

-   KASSERT(ifa->ifa_carp == NULL, ("%s: ifa %p attached", __func__, ifa));
+   if (ifa->ifa_carp != NULL)
+   return (EBUSY);

switch (ifa->ifa_addr->sa_family) {
 #ifdef INET

-- 
You are receiving this mail because:
You are the assignee for the bug.
___
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

[Bug 214832] if_pflog subrulenr incorrectly set

2016-11-25 Thread bugzilla-noreply
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214832

Mark Linimon  changed:

   What|Removed |Added

   Assignee|freebsd-b...@freebsd.org|freebsd-net@FreeBSD.org
   Keywords||patch

-- 
You are receiving this mail because:
You are the assignee for the bug.
___
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"