Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 May 2019 11:45:00 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r348324 - head/sys/net
Message-ID:  <201905281145.x4SBj0Yj094548@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Tue May 28 11:45:00 2019
New Revision: 348324
URL: https://svnweb.freebsd.org/changeset/base/348324

Log:
  Rework r348303 to reduce the time of holding global BPF lock.
  
  It appeared that using NET_EPOCH_WAIT() while holding global BPF lock
  can lead to another panic:
  
  spin lock 0xfffff800183c9840 (turnstile lock) held by 0xfffff80018e2c5a0 (tid 100325) too long
  panic: spin lock held too long
  ...
  #0  sched_switch (td=0xfffff80018e2c5a0, newtd=0xfffff8000389e000, flags=<optimized out>) at /usr/src/sys/kern/sched_ule.c:2133
  #1  0xffffffff80bf9912 in mi_switch (flags=256, newtd=0x0) at /usr/src/sys/kern/kern_synch.c:439
  #2  0xffffffff80c21db7 in sched_bind (td=<optimized out>, cpu=<optimized out>) at /usr/src/sys/kern/sched_ule.c:2704
  #3  0xffffffff80c34c33 in epoch_block_handler_preempt (global=<optimized out>, cr=0xfffffe00005a1a00, arg=<optimized out>)
      at /usr/src/sys/kern/subr_epoch.c:394
  #4  0xffffffff803c741b in epoch_block (global=<optimized out>, cr=<optimized out>, cb=<optimized out>, ct=<optimized out>)
      at /usr/src/sys/contrib/ck/src/ck_epoch.c:416
  #5  ck_epoch_synchronize_wait (global=0xfffff8000380cd80, cb=<optimized out>, ct=<optimized out>) at /usr/src/sys/contrib/ck/src/ck_epoch.c:465
  #6  0xffffffff80c3475e in epoch_wait_preempt (epoch=0xfffff8000380cd80) at /usr/src/sys/kern/subr_epoch.c:513
  #7  0xffffffff80ce970b in bpf_detachd_locked (d=0xfffff801d309cc00, detached_ifp=<optimized out>) at /usr/src/sys/net/bpf.c:856
  #8  0xffffffff80ced166 in bpf_detachd (d=<optimized out>) at /usr/src/sys/net/bpf.c:836
  #9  bpf_dtor (data=0xfffff801d309cc00) at /usr/src/sys/net/bpf.c:914
  
  To fix this add the check to the catchpacket() that BPF descriptor was
  not detached just before we acquired BPFD_LOCK().
  
  Reported by:	slavash
  Tested by:	slavash
  MFC after:	1 week

Modified:
  head/sys/net/bpf.c

Modified: head/sys/net/bpf.c
==============================================================================
--- head/sys/net/bpf.c	Tue May 28 10:55:59 2019	(r348323)
+++ head/sys/net/bpf.c	Tue May 28 11:45:00 2019	(r348324)
@@ -850,15 +850,10 @@ bpf_detachd_locked(struct bpf_d *d, bool detached_ifp)
 	/* Check if descriptor is attached */
 	if ((bp = d->bd_bif) == NULL)
 		return;
-	/*
-	 * Remove d from the interface's descriptor list.
-	 * And wait until bpf_[m]tap*() will finish their possible work
-	 * with descriptor.
-	 */
-	CK_LIST_REMOVE(d, bd_next);
-	NET_EPOCH_WAIT();
 
 	BPFD_LOCK(d);
+	/* Remove d from the interface's descriptor list. */
+	CK_LIST_REMOVE(d, bd_next);
 	/* Save bd_writer value */
 	error = d->bd_writer;
 	ifp = bp->bif_ifp;
@@ -2494,6 +2489,11 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen
 	int tstype;
 
 	BPFD_LOCK_ASSERT(d);
+	if (d->bd_bif == NULL) {
+		/* Descriptor was detached in concurrent thread */
+		counter_u64_add(d->bd_dcount, 1);
+		return;
+	}
 
 	/*
 	 * Detect whether user space has released a buffer back to us, and if



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905281145.x4SBj0Yj094548>