Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Mar 2018 20:11:12 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r331828 - in head/sys/compat/linuxkpi/common: include/linux src
Message-ID:  <201803302011.w2UKBC8q029559@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Fri Mar 30 20:11:12 2018
New Revision: 331828
URL: https://svnweb.freebsd.org/changeset/base/331828

Log:
  Optimise use of Giant in the LinuxKPI.
  
  - Make sure Giant is locked when calling PCI device methods.
  Newbus currently requires this.
  
  - Avoid unlocking Giant right before aquiring the sleepqueue lock.
  This can save a task switch.
  
  MFC after:	1 week
  Sponsored by:	Mellanox Technologies

Modified:
  head/sys/compat/linuxkpi/common/include/linux/module.h
  head/sys/compat/linuxkpi/common/src/linux_compat.c
  head/sys/compat/linuxkpi/common/src/linux_pci.c
  head/sys/compat/linuxkpi/common/src/linux_rcu.c
  head/sys/compat/linuxkpi/common/src/linux_schedule.c

Modified: head/sys/compat/linuxkpi/common/include/linux/module.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/linux/module.h	Fri Mar 30 19:58:58 2018	(r331827)
+++ head/sys/compat/linuxkpi/common/include/linux/module.h	Fri Mar 30 20:11:12 2018	(r331828)
@@ -78,9 +78,7 @@ _module_run(void *arg)
 		printf("Running %s (%p)\n", name, pc);
 #endif
 	fn = arg;
-	DROP_GIANT();
 	fn();
-	PICKUP_GIANT();
 }
 
 #define	module_init(fn)							\

Modified: head/sys/compat/linuxkpi/common/src/linux_compat.c
==============================================================================
--- head/sys/compat/linuxkpi/common/src/linux_compat.c	Fri Mar 30 19:58:58 2018	(r331827)
+++ head/sys/compat/linuxkpi/common/src/linux_compat.c	Fri Mar 30 20:11:12 2018	(r331828)
@@ -1804,8 +1804,6 @@ linux_wait_for_common(struct completion *c, int flags)
 	if (SCHEDULER_STOPPED())
 		return (0);
 
-	DROP_GIANT();
-
 	task = current;
 
 	if (flags != 0)
@@ -1819,22 +1817,25 @@ linux_wait_for_common(struct completion *c, int flags)
 			break;
 		sleepq_add(c, NULL, "completion", flags, 0);
 		if (flags & SLEEPQ_INTERRUPTIBLE) {
+			DROP_GIANT();
 			error = -sleepq_wait_sig(c, 0);
+			PICKUP_GIANT();
 			if (error != 0) {
 				linux_schedule_save_interrupt_value(task, error);
 				error = -ERESTARTSYS;
 				goto intr;
 			}
-		} else
+		} else {
+			DROP_GIANT();
 			sleepq_wait(c, 0);
+			PICKUP_GIANT();
+		}
 	}
 	if (c->done != UINT_MAX)
 		c->done--;
 	sleepq_release(c);
 
 intr:
-	PICKUP_GIANT();
-
 	return (error);
 }
 
@@ -1851,8 +1852,6 @@ linux_wait_for_timeout_common(struct completion *c, in
 	if (SCHEDULER_STOPPED())
 		return (0);
 
-	DROP_GIANT();
-
 	task = current;
 
 	if (flags != 0)
@@ -1866,10 +1865,14 @@ linux_wait_for_timeout_common(struct completion *c, in
 			break;
 		sleepq_add(c, NULL, "completion", flags, 0);
 		sleepq_set_timeout(c, linux_timer_jiffies_until(end));
+
+		DROP_GIANT();
 		if (flags & SLEEPQ_INTERRUPTIBLE)
 			error = -sleepq_timedwait_sig(c, 0);
 		else
 			error = -sleepq_timedwait(c, 0);
+		PICKUP_GIANT();
+
 		if (error != 0) {
 			/* check for timeout */
 			if (error == -EWOULDBLOCK) {
@@ -1889,8 +1892,6 @@ linux_wait_for_timeout_common(struct completion *c, in
 	/* return how many jiffies are left */
 	error = linux_timer_jiffies_until(end);
 done:
-	PICKUP_GIANT();
-
 	return (error);
 }
 

Modified: head/sys/compat/linuxkpi/common/src/linux_pci.c
==============================================================================
--- head/sys/compat/linuxkpi/common/src/linux_pci.c	Fri Mar 30 19:58:58 2018	(r331827)
+++ head/sys/compat/linuxkpi/common/src/linux_pci.c	Fri Mar 30 20:11:12 2018	(r331828)
@@ -171,12 +171,11 @@ linux_pci_attach(device_t dev)
 		pdev->bus = pbus;
 	}
 
-	DROP_GIANT();
 	spin_lock(&pci_lock);
 	list_add(&pdev->links, &pci_devices);
 	spin_unlock(&pci_lock);
+
 	error = pdrv->probe(pdev, id);
-	PICKUP_GIANT();
 	if (error) {
 		spin_lock(&pci_lock);
 		list_del(&pdev->links);
@@ -194,9 +193,9 @@ linux_pci_detach(device_t dev)
 
 	linux_set_current(curthread);
 	pdev = device_get_softc(dev);
-	DROP_GIANT();
+
 	pdev->pdrv->remove(pdev);
-	PICKUP_GIANT();
+
 	spin_lock(&pci_lock);
 	list_del(&pdev->links);
 	spin_unlock(&pci_lock);
@@ -258,11 +257,8 @@ linux_pci_shutdown(device_t dev)
 
 	linux_set_current(curthread);
 	pdev = device_get_softc(dev);
-	if (pdev->pdrv->shutdown != NULL) {
-		DROP_GIANT();
+	if (pdev->pdrv->shutdown != NULL)
 		pdev->pdrv->shutdown(pdev);
-		PICKUP_GIANT();
-	}
 	return (0);
 }
 

Modified: head/sys/compat/linuxkpi/common/src/linux_rcu.c
==============================================================================
--- head/sys/compat/linuxkpi/common/src/linux_rcu.c	Fri Mar 30 19:58:58 2018	(r331827)
+++ head/sys/compat/linuxkpi/common/src/linux_rcu.c	Fri Mar 30 20:11:12 2018	(r331828)
@@ -297,13 +297,13 @@ linux_synchronize_rcu(void)
 
 	td = curthread;
 
-	DROP_GIANT();
-
 	/*
 	 * Synchronizing RCU might change the CPU core this function
 	 * is running on. Save current values:
 	 */
 	thread_lock(td);
+
+	DROP_GIANT();
 
 	old_cpu = PCPU_GET(cpuid);
 	old_pinned = td->td_pinned;

Modified: head/sys/compat/linuxkpi/common/src/linux_schedule.c
==============================================================================
--- head/sys/compat/linuxkpi/common/src/linux_schedule.c	Fri Mar 30 19:58:58 2018	(r331827)
+++ head/sys/compat/linuxkpi/common/src/linux_schedule.c	Fri Mar 30 20:11:12 2018	(r331828)
@@ -55,6 +55,8 @@ linux_add_to_sleepqueue(void *wchan, struct task_struc
 	sleepq_add(wchan, NULL, wmesg, flags, 0);
 	if (timeout != 0)
 		sleepq_set_timeout(wchan, timeout);
+
+	DROP_GIANT();
 	if ((state & TASK_INTERRUPTIBLE) != 0) {
 		if (timeout == 0)
 			ret = -sleepq_wait_sig(wchan, 0);
@@ -67,6 +69,8 @@ linux_add_to_sleepqueue(void *wchan, struct task_struc
 		} else
 			ret = -sleepq_timedwait(wchan, 0);
 	}
+	PICKUP_GIANT();
+
 	/* filter return value */
 	if (ret != 0 && ret != -EWOULDBLOCK) {
 		linux_schedule_save_interrupt_value(task, ret);
@@ -248,8 +252,6 @@ linux_wait_event_common(wait_queue_head_t *wqh, wait_q
 	if (lock != NULL)
 		spin_unlock_irq(lock);
 
-	DROP_GIANT();
-
 	/* range check timeout */
 	if (timeout < 1)
 		timeout = 1;
@@ -272,8 +274,6 @@ linux_wait_event_common(wait_queue_head_t *wqh, wait_q
 	}
 	PRELE(task->task_thread->td_proc);
 
-	PICKUP_GIANT();
-
 	if (lock != NULL)
 		spin_lock_irq(lock);
 	return (ret);
@@ -297,8 +297,6 @@ linux_schedule_timeout(int timeout)
 
 	remainder = ticks + timeout;
 
-	DROP_GIANT();
-
 	sleepq_lock(task);
 	state = atomic_read(&task->state);
 	if (state != TASK_WAKING) {
@@ -309,8 +307,6 @@ linux_schedule_timeout(int timeout)
 	}
 	set_task_state(task, TASK_RUNNING);
 
-	PICKUP_GIANT();
-
 	if (timeout == 0)
 		return (MAX_SCHEDULE_TIMEOUT);
 
@@ -356,8 +352,6 @@ linux_wait_on_bit_timeout(unsigned long *word, int bit
 	void *wchan;
 	int ret;
 
-	DROP_GIANT();
-
 	/* range check timeout */
 	if (timeout < 1)
 		timeout = 1;
@@ -380,8 +374,6 @@ linux_wait_on_bit_timeout(unsigned long *word, int bit
 	}
 	set_task_state(task, TASK_RUNNING);
 
-	PICKUP_GIANT();
-
 	return (ret);
 }
 
@@ -399,8 +391,6 @@ linux_wait_on_atomic_t(atomic_t *a, unsigned int state
 	void *wchan;
 	int ret;
 
-	DROP_GIANT();
-
 	task = current;
 	wchan = a;
 	for (;;) {
@@ -416,8 +406,6 @@ linux_wait_on_atomic_t(atomic_t *a, unsigned int state
 			break;
 	}
 	set_task_state(task, TASK_RUNNING);
-
-	PICKUP_GIANT();
 
 	return (ret);
 }



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