mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: ACPI Devel Maling List <linux-acpi@vger.kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Bjorn Helgaas <bhelgaas@google.com>, Jiang Liu <liuj97@gmail.com>,
	Yinghai Lu <yinghai@kernel.org>,
	"Alexander E. Patrakov" <patrakov@gmail.com>
Subject: [PATCH 1/3] ACPI / dock: Rework the handling of notifications
Date: Sat, 29 Jun 2013 00:53:35 +0200	[thread overview]
Message-ID: <1771749.8rDXNf8giR@vostro.rjw.lan> (raw)
In-Reply-To: <1515394.L46AJCfCTt@vostro.rjw.lan>

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The ACPI dock driver uses register_acpi_bus_notifier() which
installs a notifier triggered globally for all system notifications.
That first of all is inefficient, because the dock driver is only
interested in notifications associated with the devices it handles,
but it has to handle all system notifies for all devices.  Moreover,
it does that even if no docking stations are present in the system
(CONFIG_ACPI_DOCK set is sufficient for that to happen).  Besides,
that is inconvenient, because it requires the driver to do extra work
for each notification to find the target dock station object.

For these reasons, rework the dock driver to install a notify
handler individually for each dock station in the system using
acpi_install_notify_handler().  This allows the dock station
object to be passed directly to the notify handler and makes it
possible to simplify the dock driver quite a bit.  It also
reduces the overhead related to the handling of all system
notifies when CONFIG_ACPI_DOCK is set.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/dock.c |   69 ++++++++++++++++++----------------------------------
 1 file changed, 25 insertions(+), 44 deletions(-)

Index: linux-pm/drivers/acpi/dock.c
===================================================================
--- linux-pm.orig/drivers/acpi/dock.c
+++ linux-pm/drivers/acpi/dock.c
@@ -718,18 +718,17 @@ static int handle_eject_request(struct d
 
 /**
  * dock_notify - act upon an acpi dock notification
- * @handle: the dock station handle
+ * @ds: dock station
  * @event: the acpi event
- * @data: our driver data struct
  *
  * If we are notified to dock, then check to see if the dock is
  * present and then dock.  Notify all drivers of the dock event,
  * and then hotplug and devices that may need hotplugging.
  */
-static void dock_notify(acpi_handle handle, u32 event, void *data)
+static void dock_notify(struct dock_station *ds, u32 event)
 {
-	struct dock_station *ds = data;
-	struct acpi_device *tmp;
+	acpi_handle handle = ds->handle;
+	struct acpi_device *ad;
 	int surprise_removal = 0;
 
 	/*
@@ -752,8 +751,7 @@ static void dock_notify(acpi_handle hand
 	switch (event) {
 	case ACPI_NOTIFY_BUS_CHECK:
 	case ACPI_NOTIFY_DEVICE_CHECK:
-		if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
-		   &tmp)) {
+		if (!dock_in_progress(ds) && acpi_bus_get_device(handle, &ad)) {
 			begin_dock(ds);
 			dock(ds);
 			if (!dock_present(ds)) {
@@ -790,9 +788,8 @@ static void dock_notify(acpi_handle hand
 }
 
 struct dock_data {
-	acpi_handle handle;
-	unsigned long event;
 	struct dock_station *ds;
+	u32 event;
 };
 
 static void acpi_dock_deferred_cb(void *context)
@@ -800,52 +797,31 @@ static void acpi_dock_deferred_cb(void *
 	struct dock_data *data = context;
 
 	acpi_scan_lock_acquire();
-	dock_notify(data->handle, data->event, data->ds);
+	dock_notify(data->ds, data->event);
 	acpi_scan_lock_release();
 	kfree(data);
 }
 
-static int acpi_dock_notifier_call(struct notifier_block *this,
-	unsigned long event, void *data)
+static void dock_notify_handler(acpi_handle handle, u32 event, void *data)
 {
-	struct dock_station *dock_station;
-	acpi_handle handle = data;
+	struct dock_data *dd;
 
 	if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
 	   && event != ACPI_NOTIFY_EJECT_REQUEST)
-		return 0;
-
-	acpi_scan_lock_acquire();
+		return;
 
-	list_for_each_entry(dock_station, &dock_stations, sibling) {
-		if (dock_station->handle == handle) {
-			struct dock_data *dd;
-			acpi_status status;
-
-			dd = kmalloc(sizeof(*dd), GFP_KERNEL);
-			if (!dd)
-				break;
-
-			dd->handle = handle;
-			dd->event = event;
-			dd->ds = dock_station;
-			status = acpi_os_hotplug_execute(acpi_dock_deferred_cb,
-							 dd);
-			if (ACPI_FAILURE(status))
-				kfree(dd);
-
-			break;
-		}
+	dd = kmalloc(sizeof(*dd), GFP_KERNEL);
+	if (dd) {
+		acpi_status status;
+
+		dd->ds = data;
+		dd->event = event;
+		status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd);
+		if (ACPI_FAILURE(status))
+			kfree(dd);
 	}
-
-	acpi_scan_lock_release();
-	return 0;
 }
 
-static struct notifier_block dock_acpi_notifier = {
-	.notifier_call = acpi_dock_notifier_call,
-};
-
 /**
  * find_dock_devices - find devices on the dock station
  * @handle: the handle of the device we are examining
@@ -979,6 +955,7 @@ static int __init dock_add(acpi_handle h
 	int ret, id;
 	struct dock_station ds, *dock_station;
 	struct platform_device *dd;
+	acpi_status status;
 
 	id = dock_station_count;
 	memset(&ds, 0, sizeof(ds));
@@ -1021,6 +998,11 @@ static int __init dock_add(acpi_handle h
 	if (ret)
 		goto err_rmgroup;
 
+	status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+					     dock_notify_handler, dock_station);
+	if (ACPI_FAILURE(status))
+		goto err_rmgroup;
+
 	dock_station_count++;
 	list_add(&dock_station->sibling, &dock_stations);
 	return 0;
@@ -1065,7 +1047,6 @@ int __init acpi_dock_init(void)
 		return 0;
 	}
 
-	register_acpi_bus_notifier(&dock_acpi_notifier);
 	pr_info(PREFIX "%s: %d docks/bays found\n",
 		ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
 	return 0;


  reply	other threads:[~2013-06-28 22:46 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-28 19:44 [PATCH 0/4] ACPI / dock: Cleanups and simplifications Rafael J. Wysocki
2013-06-28 19:45 ` [PATCH 1/4] ACPI / dock: Drop the hp_lock mutex from struct dock_station Rafael J. Wysocki
2013-06-28 19:46 ` [PATCH 2/4] ACPI / dock: Rework and simplify find_dock_devices() Rafael J. Wysocki
2013-06-28 20:08   ` Yinghai Lu
2013-06-28 19:47 ` [PATCH 3/4] ACPI / dock: Walk list in reverse order during removal of devices Rafael J. Wysocki
2013-06-28 20:14   ` Yinghai Lu
2013-06-28 19:48 ` [PATCH 4/4] ACPI / dock: Simplify dock_init_hotplug() and dock_release_hotplug() Rafael J. Wysocki
2013-06-28 20:16   ` Yinghai Lu
2013-06-28 22:47 ` [PATCH 0/3] ACPI / dock: Notification rework and memory leak fix Rafael J. Wysocki
2013-06-28 22:53   ` Rafael J. Wysocki [this message]
2013-06-28 23:34     ` [PATCH 1/3] ACPI / dock: Rework the handling of notifications Yinghai Lu
2013-06-29 11:16       ` Rafael J. Wysocki
2013-06-29 16:12         ` Yinghai Lu
2013-06-30 14:18           ` Rafael J. Wysocki
2013-07-01 20:21     ` Bjorn Helgaas
2013-07-02  1:28       ` Rafael J. Wysocki
2013-06-28 22:54   ` [PATCH 2/3] ACPI: Drop ACPI bus notifier call chain Rafael J. Wysocki
2013-06-28 22:54   ` [PATCH 3/3] ACPI / dock: Do not leak memory on falilures to add a dock station Rafael J. Wysocki
2013-07-03 23:23   ` [PATCH 0/4] ACPI / dock: One fix and more cleanups Rafael J. Wysocki
2013-07-03 23:25     ` [PATCH 1/4] ACPI / dock: Actually define acpi_dock_init() as void Rafael J. Wysocki
2013-07-03 23:26     ` [PATCH 2/4] ACPI / dock: Do not check CONFIG_ACPI_DOCK_MODULE Rafael J. Wysocki
2013-07-03 23:27     ` [PATCH 3/4] ACPI / dock / PCI: Drop ACPI dock notifier chain Rafael J. Wysocki
2013-07-03 23:28     ` [PATCH 4/4] ACPI / dock: Drop unnecessary local variable from dock_add() Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1771749.8rDXNf8giR@vostro.rjw.lan \
    --to=rjw@sisk.pl \
    --cc=bhelgaas@google.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liuj97@gmail.com \
    --cc=patrakov@gmail.com \
    --cc=yinghai@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®