svn commit: r319198 - head/sys/dev/ena

Zbigniew Bodek zbb at FreeBSD.org
Tue May 30 11:55:04 UTC 2017


Author: zbb
Date: Tue May 30 11:55:02 2017
New Revision: 319198
URL: https://svnweb.freebsd.org/changeset/base/319198

Log:
  Add locks before each ena_up and ena_down
  
  Lock only ena_up and ena_down calls in ioctl handler, instead of whole
  ioctl. Locking ioctl with sx lock that is sleepable, is not allowed in
  some cases, e.g. when multicast options are being changed.
  Additional locking was added in deatch function to prevent race condition
  with ioctl function.
  
  Submitted by:   Michal Krawczyk <mk at semihalf.com>
  Obtained from:  Semihalf
  Sponsored by:   Amazon.com Inc.
  Differential revision: https://reviews.freebsd.org/D10924

Modified:
  head/sys/dev/ena/ena.c

Modified: head/sys/dev/ena/ena.c
==============================================================================
--- head/sys/dev/ena/ena.c	Tue May 30 11:53:18 2017	(r319197)
+++ head/sys/dev/ena/ena.c	Tue May 30 11:55:02 2017	(r319198)
@@ -2285,16 +2285,16 @@ ena_ioctl(if_t ifp, u_long command, caddr_t data)
 	/*
 	 * Acquiring lock to prevent from running up and down routines parallel.
 	 */
-	sx_xlock(&adapter->ioctl_sx);
-
 	rc = 0;
 	switch (command) {
 	case SIOCSIFMTU:
+		sx_xlock(&adapter->ioctl_sx);
 		ena_down(adapter);
 
 		ena_change_mtu(ifp, ifr->ifr_mtu);
 
 		rc = ena_up(adapter);
+		sx_unlock(&adapter->ioctl_sx);
 		break;
 
 	case SIOCSIFFLAGS:
@@ -2306,11 +2306,16 @@ ena_ioctl(if_t ifp, u_long command, caddr_t data)
 					    "ioctl promisc/allmulti\n");
 				}
 			} else {
+				sx_xlock(&adapter->ioctl_sx);
 				rc = ena_up(adapter);
+				sx_unlock(&adapter->ioctl_sx);
 			}
 		} else {
-			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+				sx_xlock(&adapter->ioctl_sx);
 				ena_down(adapter);
+				sx_unlock(&adapter->ioctl_sx);
+			}
 		}
 		break;
 
@@ -2333,8 +2338,10 @@ ena_ioctl(if_t ifp, u_long command, caddr_t data)
 			}
 
 			if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+				sx_xlock(&adapter->ioctl_sx);
 				ena_down(adapter);
 				rc = ena_up(adapter);
+				sx_unlock(&adapter->ioctl_sx);
 			}
 		}
 
@@ -2344,8 +2351,6 @@ ena_ioctl(if_t ifp, u_long command, caddr_t data)
 		break;
 	}
 
-	sx_unlock(&adapter->ioctl_sx);
-
 	return (rc);
 }
 
@@ -3666,7 +3671,9 @@ ena_detach(device_t pdev)
 		taskqueue_drain(adapter->reset_tq, &adapter->reset_task);
 	taskqueue_free(adapter->reset_tq);
 
+	sx_xlock(&adapter->ioctl_sx);
 	ena_down(adapter);
+	sx_unlock(&adapter->ioctl_sx);
 
 	if (adapter->ifp != NULL) {
 		ether_ifdetach(adapter->ifp);


More information about the svn-src-all mailing list