linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PATCH: platforms: avoid queuing work if possible
@ 2014-01-31  1:24 Peter Chang
  2014-01-31 11:53 ` Tejun Heo
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Chang @ 2014-01-31  1:24 UTC (permalink / raw)
  To: linux-pci@vger.kernel.org, tj

[-- Attachment #1: Type: text/plain, Size: 267 bytes --]

we noticed a change in module loading behavior and tracked it
backwards to a small change in behavior due to
774a1221e862b343388347bac9b318767336b20b. this tries to avoid queuing
if possible, but if we do queue then copy the relevant task flag on
the target cpu.

\p

[-- Attachment #2: 0001-platforms-avoid-queuing-work-if-possible.patch --]
[-- Type: text/x-patch, Size: 2686 bytes --]

From 9e77188d8a8e74b7b4e3f3e7c6bb0deb8fdf7eb4 Mon Sep 17 00:00:00 2001
From: peter chang <dpf@google.com>
Date: Mon, 27 Jan 2014 16:24:53 -0800
Subject: [PATCH] platforms: avoid queuing work if possible

774a1221e862b343388347bac9b318767336b20b tries to avoid an expensive sync
by marking the current task iff it uses the async_schedule() machinery.
however, if the part of the driver's probe is called through a worker
thread the bookeeping fails to mark the correct task as having used the
async machinery.

this is a workaround for the common case that we're already running
on the correct cpu. however, it seems sort of reasonable to not use
the worker thread if we don't have to.

Tested:
- checked on vebmy2 (ibis + satasquatch) which is where the original issue
  was discovered.
- checked on fdha347 (ikaria + loggerhead + satasquatch) to show that
  nothing changed.

Change-Id: Ibe8996cf652735c74a9e06ba9fd03118078395bd
Google-Bug-Id: 12632867
Signed-off-by: peter chang <dpf@google.com>
---
 drivers/pci/pci-driver.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e6515e2..9f7e1e9 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -243,6 +243,7 @@ struct drv_dev_and_id {
 	struct pci_driver *drv;
 	struct pci_dev *dev;
 	const struct pci_device_id *id;
+	unsigned int task_flags;
 };
 
 static long local_pci_probe(void *_ddi)
@@ -267,7 +268,8 @@ static long local_pci_probe(void *_ddi)
 	if (rc) {
 		pci_dev->driver = NULL;
 		pm_runtime_put_sync(dev);
-	}
+	} else if (current)
+		ddi->task_flags = current->flags;
 	return rc;
 }
 
@@ -275,7 +277,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
 			  const struct pci_device_id *id)
 {
 	int error, node;
-	struct drv_dev_and_id ddi = { drv, dev, id };
+	struct drv_dev_and_id ddi = { drv, dev, id, 0 };
 
 	/* Execute driver initialization on node where the device's
 	   bus is attached to.  This way the driver likely allocates
@@ -287,9 +289,16 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
 
 		get_online_cpus();
 		cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask);
-		if (cpu < nr_cpu_ids)
+		/* try not to queue work if we're already on the target cpu */
+		if (cpu < nr_cpu_ids && cpu != get_cpu()) {
 			error = work_on_cpu(cpu, local_pci_probe, &ddi);
-		else
+			/* copy out some task flags for the module loading
+			 * case.
+			 */
+			if (!error && current)
+				current->flags |= (ddi.task_flags &
+						   PF_USED_ASYNC);
+		} else
 			error = local_pci_probe(&ddi);
 		put_online_cpus();
 	} else
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-02-10 22:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-31  1:24 PATCH: platforms: avoid queuing work if possible Peter Chang
2014-01-31 11:53 ` Tejun Heo
2014-01-31 12:00   ` Tejun Heo
2014-02-05  4:13   ` Peter Chang
2014-02-10 22:41     ` Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).