Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Oct 2018 04:37:29 +0000 (UTC)
From:      Eric Joyner <erj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r339634 - in head/sys: kern net
Message-ID:  <201810230437.w9N4bTxf050789@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: erj
Date: Tue Oct 23 04:37:29 2018
New Revision: 339634
URL: https://svnweb.freebsd.org/changeset/base/339634

Log:
  iflib: drain enqueued tasks before detaching from taskqgroup
  
  The taskqgroup_detach function does not check if task is already enqueued when
  detaching it. This may lead to kernel panic if enqueued task starts after
  context state lock is destroyed. Ensure that the already enqueued admin tasks
  are executed before detaching them.
  
  The issue was discovered during validation of D16429. Unloading of if_ixlv
  followed by immediate removal of VFs with iovctl -D may lead to panic on
  NODEBUG kernel.
  
  As well, check if iflib is in detach before enqueueing new admin or iov
  tasks, to prevent new tasks from executing while the taskqgroup tasks
  are being drained.
  
  Submitted by:	Krzysztof Galazka <krzysztof.galazka@intel.com>
  Reviewed by:	shurd@, erj@
  Sponsored by:	Intel Corporation
  Differential Revision:	https://reviews.freebsd.org/D17404

Modified:
  head/sys/kern/subr_gtaskqueue.c
  head/sys/net/iflib.c

Modified: head/sys/kern/subr_gtaskqueue.c
==============================================================================
--- head/sys/kern/subr_gtaskqueue.c	Tue Oct 23 03:30:14 2018	(r339633)
+++ head/sys/kern/subr_gtaskqueue.c	Tue Oct 23 04:37:29 2018	(r339634)
@@ -812,6 +812,7 @@ taskqgroup_detach(struct taskqgroup *qgroup, struct gr
 	qgroup->tqg_queue[i].tgc_cnt--;
 	LIST_REMOVE(gtask, gt_list);
 	mtx_unlock(&qgroup->tqg_lock);
+	gtaskqueue_drain(gtask->gt_taskqueue, &gtask->gt_task);
 	gtask->gt_taskqueue = NULL;
 }
 

Modified: head/sys/net/iflib.c
==============================================================================
--- head/sys/net/iflib.c	Tue Oct 23 03:30:14 2018	(r339633)
+++ head/sys/net/iflib.c	Tue Oct 23 04:37:29 2018	(r339634)
@@ -2279,8 +2279,8 @@ iflib_timer(void *arg)
 	STATE_LOCK(ctx);
 	if_setdrvflagbits(ctx->ifc_ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING);
 	ctx->ifc_flags |= (IFC_DO_WATCHDOG|IFC_DO_RESET);
-	iflib_admin_intr_deferred(ctx);
 	STATE_UNLOCK(ctx);
+	iflib_admin_intr_deferred(ctx);
 }
 
 static void
@@ -2802,8 +2802,8 @@ iflib_rxeof(iflib_rxq_t rxq, qidx_t budget)
 err:
 	STATE_LOCK(ctx);
 	ctx->ifc_flags |= IFC_DO_RESET;
-	iflib_admin_intr_deferred(ctx);
 	STATE_UNLOCK(ctx);
+	iflib_admin_intr_deferred(ctx);
 	return (false);
 }
 
@@ -5973,7 +5973,10 @@ iflib_admin_intr_deferred(if_ctx_t ctx)
 {
 #ifdef INVARIANTS
 	struct grouptask *gtask;
-
+#endif
+	if (iflib_in_detach(ctx))
+		return;
+#ifdef INVARIANTS
 	gtask = &ctx->ifc_admin_task;
 	MPASS(gtask != NULL && gtask->gt_taskqueue != NULL);
 #endif
@@ -5984,6 +5987,8 @@ iflib_admin_intr_deferred(if_ctx_t ctx)
 void
 iflib_iov_intr_deferred(if_ctx_t ctx)
 {
+	if (iflib_in_detach(ctx))
+		return;
 
 	GROUPTASK_ENQUEUE(&ctx->ifc_vflr_task);
 }



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