[PATCH 2/3] acpi: semaphore removal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The semaphore is used pretty extensively in acpi, but the actual
usage model is really more like completions. The ASL functions
getting implemented here are signals which follow a "wait for",
signaled, or rest format.

This implements the ACPI signaling methods with the Linux
completion API, instead of using semaphores.

completion_done() taken from Dave Chinner.

Cc: len.brown@xxxxxxxxx
Cc: linux-acpi@xxxxxxxxxxxxxxx
Cc: Dave Chinner <david@xxxxxxxxxxxxx>
Signed-off-by: Daniel Walker <dwalker@xxxxxxxxxx>
---
 drivers/acpi/events/evmisc.c      |   12 ++++----
 drivers/acpi/executer/excreate.c  |   10 +++---
 drivers/acpi/executer/exdump.c    |    2 +-
 drivers/acpi/executer/exsystem.c  |   22 +++++++-------
 drivers/acpi/namespace/nsaccess.c |    4 +-
 drivers/acpi/osl.c                |   60 ++++++++++++++++++------------------
 drivers/acpi/utilities/utdelete.c |   12 ++++----
 drivers/acpi/utilities/utglobal.c |    2 +-
 include/acpi/acglobal.h           |    4 +-
 include/acpi/acinterp.h           |    2 +-
 include/acpi/acobject.h           |    2 +-
 include/acpi/acpiosxf.h           |   10 +++---
 include/acpi/actypes.h            |    2 +-
 include/linux/completion.h        |   19 +++++++++++
 14 files changed, 91 insertions(+), 72 deletions(-)

diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 1d5670b..b0bd8f7 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -283,7 +283,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
  *              release interrupt occurs. Attempt to acquire the global lock,
  *              if successful, signal the thread waiting for the lock.
  *
- * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
+ * NOTE: Assumes that the completion can be signaled from interrupt level. If
  * this is not possible for some reason, a separate thread will have to be
  * scheduled to do this.
  *
@@ -305,13 +305,13 @@ static u32 acpi_ev_global_lock_handler(void *context)
 		/* Got the lock, now wake all threads waiting for it */
 
 		acpi_gbl_global_lock_acquired = TRUE;
-		/* Send a unit to the semaphore */
+		/* Send a unit to the completion */
 
 		if (ACPI_FAILURE
-		    (acpi_os_signal_semaphore
-		     (acpi_gbl_global_lock_semaphore, 1))) {
+		    (acpi_os_signal_complete
+		     (acpi_gbl_global_lock_completion, 1))) {
 			ACPI_ERROR((AE_INFO,
-				    "Could not signal Global Lock semaphore"));
+				    "Could not signal Global Lock completion"));
 		}
 	}
 
@@ -494,7 +494,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
 	 * Wait for handshake with the global lock interrupt handler.
 	 * This interface releases the interpreter if we must wait.
 	 */
-	status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
+	status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_completion,
 					       ACPI_WAIT_FOREVER);
 
 	return_ACPI_STATUS(status);
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index ad09696..625be14 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -180,11 +180,11 @@ acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state)
 	}
 
 	/*
-	 * Create the actual OS semaphore, with zero initial units -- meaning
+	 * Create the actual OS completion, with zero initial units -- meaning
 	 * that the event is created in an unsignalled state
 	 */
-	status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
-					  &obj_desc->event.os_semaphore);
+	status = acpi_os_create_completion(ACPI_NO_UNIT_LIMIT, 0,
+					  &obj_desc->event.os_completion);
 	if (ACPI_FAILURE(status)) {
 		goto cleanup;
 	}
@@ -198,7 +198,7 @@ acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state)
       cleanup:
 	/*
 	 * Remove local reference to the object (on error, will cause deletion
-	 * of both object and semaphore if present.)
+	 * of both object and completion if present.)
 	 */
 	acpi_ut_remove_reference(obj_desc);
 	return_ACPI_STATUS(status);
@@ -254,7 +254,7 @@ acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state)
       cleanup:
 	/*
 	 * Remove local reference to the object (on error, will cause deletion
-	 * of both object and semaphore if present.)
+	 * of both object and completion if present.)
 	 */
 	acpi_ut_remove_reference(obj_desc);
 	return_ACPI_STATUS(status);
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 2be2e2b..9182ae4 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -117,7 +117,7 @@ static struct acpi_exdump_info acpi_ex_dump_device[4] = {
 
 static struct acpi_exdump_info acpi_ex_dump_event[2] = {
 	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_event), NULL},
-	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"}
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_completion), "OsSemaphore"}
 };
 
 static struct acpi_exdump_info acpi_ex_dump_method[8] = {
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 68990f1..f35508a 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -62,13 +62,13 @@ ACPI_MODULE_NAME("exsystem")
  *              interpreter is released before waiting.
  *
  ******************************************************************************/
-acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
+acpi_status acpi_ex_system_wait_semaphore(acpi_completion comp, u16 timeout)
 {
 	acpi_status status;
 
-	ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
+	ACPI_FUNCTION_TRACE(ex_system_wait_for_completion);
 
-	status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT);
+	status = acpi_os_wait_for_completion(comp, 1, ACPI_DO_NOT_WAIT);
 	if (ACPI_SUCCESS(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -79,7 +79,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 
 		acpi_ex_relinquish_interpreter();
 
-		status = acpi_os_wait_semaphore(semaphore, 1, timeout);
+		status = acpi_os_wait_for_completion(comp, 1, timeout);
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "*** Thread awake after blocking, %s\n",
@@ -229,7 +229,7 @@ acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
 
 	if (obj_desc) {
 		status =
-		    acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1);
+		    acpi_os_signal_complete(obj_desc->event.os_completion, 1);
 	}
 
 	return_ACPI_STATUS(status);
@@ -260,7 +260,7 @@ acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
 
 	if (obj_desc) {
 		status =
-		    acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore,
+		    acpi_ex_system_wait_semaphore(obj_desc->event.os_completion,
 						  (u16) time_desc->integer.
 						  value);
 	}
@@ -283,19 +283,19 @@ acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
 acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)
 {
 	acpi_status status = AE_OK;
-	acpi_semaphore temp_semaphore;
+	acpi_completion temp_completion;
 
 	ACPI_FUNCTION_ENTRY();
 
 	/*
-	 * We are going to simply delete the existing semaphore and
+	 * We are going to simply delete the existing completion and
 	 * create a new one!
 	 */
 	status =
-	    acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
+	    acpi_os_create_completion(ACPI_NO_UNIT_LIMIT, 0, &temp_completion);
 	if (ACPI_SUCCESS(status)) {
-		(void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore);
-		obj_desc->event.os_semaphore = temp_semaphore;
+		(void)acpi_os_delete_completion(obj_desc->event.os_completion);
+		obj_desc->event.os_completion = temp_completion;
 	}
 
 	return (status);
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index c39a7f6..fc54f45 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -213,8 +213,8 @@ acpi_status acpi_ns_root_initialize(void)
 					/* Create additional counting semaphore for global lock */
 
 					status =
-					    acpi_os_create_semaphore(1, 0,
-								     &acpi_gbl_global_lock_semaphore);
+					    acpi_os_create_completion(1, 0,
+								     &acpi_gbl_global_lock_completion);
 					if (ACPI_FAILURE(status)) {
 						acpi_ut_remove_reference
 						    (obj_desc);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 8546f59..3cb9b89 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -43,7 +43,7 @@
 #include <linux/ioport.h>
 #include <linux/list.h>
 #include <linux/jiffies.h>
-#include <linux/semaphore.h>
+#include <linux/completion.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -766,44 +766,44 @@ void acpi_os_delete_lock(acpi_spinlock handle)
 }
 
 acpi_status
-acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
+acpi_os_create_completion(u32 max_units, u32 initial_units, acpi_handle * handle)
 {
-	struct semaphore *sem = NULL;
+	struct completion *comp = NULL;
 
-	sem = acpi_os_allocate(sizeof(struct semaphore));
-	if (!sem)
+	comp = acpi_os_allocate(sizeof(struct completion));
+	if (!comp)
 		return AE_NO_MEMORY;
-	memset(sem, 0, sizeof(struct semaphore));
+	memset(comp, 0, sizeof(struct completion));
 
-	sema_init(sem, initial_units);
+	init_completion(comp);
 
-	*handle = (acpi_handle *) sem;
+	*handle = (acpi_handle *) comp;
 
-	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating completion[%p|%d].\n",
 			  *handle, initial_units));
 
 	return AE_OK;
 }
 
 /*
- * TODO: A better way to delete semaphores?  Linux doesn't have a
- * 'delete_semaphore()' function -- may result in an invalid
+ * TODO: A better way to delete completions?  Linux doesn't have a
+ * 'delete_completions()' function -- may result in an invalid
  * pointer dereference for non-synchronized consumers.	Should
  * we at least check for blocked threads and signal/cancel them?
  */
 
-acpi_status acpi_os_delete_semaphore(acpi_handle handle)
+acpi_status acpi_os_delete_completion(acpi_handle handle)
 {
-	struct semaphore *sem = (struct semaphore *)handle;
+	struct completion *comp = (struct completion *)handle;
 
-	if (!sem)
+	if (!comp)
 		return AE_BAD_PARAMETER;
 
-	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
+	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting completion[%p].\n", handle));
 
-	BUG_ON(!list_empty(&sem->wait_list));
-	kfree(sem);
-	sem = NULL;
+	BUG_ON(!completion_done(comp));
+	kfree(comp);
+	comp = NULL;
 
 	return AE_OK;
 }
@@ -811,20 +811,20 @@ acpi_status acpi_os_delete_semaphore(acpi_handle handle)
 /*
  * TODO: Support for units > 1?
  */
-acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
+acpi_status acpi_os_wait_for_completion(acpi_handle handle, u32 units, u16 timeout)
 {
 	acpi_status status = AE_OK;
-	struct semaphore *sem = (struct semaphore *)handle;
+	struct completion *comp = (struct completion *)handle;
 	long jiffies;
 	int ret = 0;
 
-	if (!sem || (units < 1))
+	if (!comp || (units < 1))
 		return AE_BAD_PARAMETER;
 
 	if (units > 1)
 		return AE_SUPPORT;
 
-	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for completion[%p|%d|%d]\n",
 			  handle, units, timeout));
 
 	if (timeout == ACPI_WAIT_FOREVER)
@@ -832,18 +832,18 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
 	else
 		jiffies = msecs_to_jiffies(timeout);
 	
-	ret = down_timeout(sem, jiffies);
+	ret = wait_for_completion_timeout(comp, jiffies);
 	if (ret)
 		status = AE_TIME;
 
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
-				  "Failed to acquire semaphore[%p|%d|%d], %s",
+				  "Failed to acquire completion[%p|%d|%d], %s",
 				  handle, units, timeout,
 				  acpi_format_exception(status)));
 	} else {
 		ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
-				  "Acquired semaphore[%p|%d|%d]", handle,
+				  "Acquired completion[%p|%d|%d]", handle,
 				  units, timeout));
 	}
 
@@ -853,20 +853,20 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
 /*
  * TODO: Support for units > 1?
  */
-acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
+acpi_status acpi_os_signal_complete(acpi_handle handle, u32 units)
 {
-	struct semaphore *sem = (struct semaphore *)handle;
+	struct completion *comp = (struct completion *)handle;
 
-	if (!sem || (units < 1))
+	if (!comp || (units < 1))
 		return AE_BAD_PARAMETER;
 
 	if (units > 1)
 		return AE_SUPPORT;
 
-	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle,
+	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling completion[%p|%d]\n", handle,
 			  units));
 
-	up(sem);
+	complete(comp);
 
 	return AE_OK;
 }
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index c5c791a..95d557e 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -163,9 +163,9 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
 			/* Global Lock has extra semaphore */
 
 			(void)
-			    acpi_os_delete_semaphore
-			    (acpi_gbl_global_lock_semaphore);
-			acpi_gbl_global_lock_semaphore = NULL;
+			    acpi_os_delete_completion
+			    (acpi_gbl_global_lock_completion);
+			acpi_gbl_global_lock_completion = NULL;
 
 			acpi_os_delete_mutex(object->mutex.os_mutex);
 			acpi_gbl_global_lock_mutex = NULL;
@@ -179,10 +179,10 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
 
 		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
 				  "***** Event %p, OS Semaphore %p\n",
-				  object, object->event.os_semaphore));
+				  object, object->event.os_completion));
 
-		(void)acpi_os_delete_semaphore(object->event.os_semaphore);
-		object->event.os_semaphore = NULL;
+		(void)acpi_os_delete_completion(object->event.os_completion);
+		object->event.os_completion = NULL;
 		break;
 
 	case ACPI_TYPE_METHOD:
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index a6e71b8..a0ef412 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -727,7 +727,7 @@ void acpi_ut_init_globals(void)
 
 	/* Global Lock support */
 
-	acpi_gbl_global_lock_semaphore = NULL;
+	acpi_gbl_global_lock_completion = NULL;
 	acpi_gbl_global_lock_mutex = NULL;
 	acpi_gbl_global_lock_acquired = FALSE;
 	acpi_gbl_global_lock_handle = 0;
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index 15dda46..50f520f 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -171,10 +171,10 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX];
 
 /*
  * Global lock mutex is an actual AML mutex object
- * Global lock semaphore works in conjunction with the HW global lock
+ * System Global lock works in conjunction with the HW global lock
  */
 ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex;
-ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore;
+ACPI_EXTERN acpi_completion acpi_gbl_global_lock_completion;
 ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
 ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
 ACPI_EXTERN u8 acpi_gbl_global_lock_present;
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index e8db7a3..daaa478 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -291,7 +291,7 @@ acpi_ex_system_wait_event(union acpi_operand_object *time,
 acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc);
 
 acpi_status
-acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout);
+acpi_ex_system_wait_semaphore(acpi_completion semaphore, u16 timeout);
 
 acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout);
 
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
index e9657da..f63117d 100644
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -149,7 +149,7 @@ struct acpi_object_package {
  *****************************************************************************/
 
 struct acpi_object_event {
-	ACPI_OBJECT_COMMON_HEADER acpi_semaphore os_semaphore;	/* Actual OS synchronization object */
+	ACPI_OBJECT_COMMON_HEADER acpi_completion os_completion;	/* Actual OS synchronization object */
 };
 
 struct acpi_object_mutex {
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 9032ec3..140e078 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -110,15 +110,15 @@ void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags);
  * Semaphore primitives
  */
 acpi_status
-acpi_os_create_semaphore(u32 max_units,
-			 u32 initial_units, acpi_semaphore * out_handle);
+acpi_os_create_completion(u32 max_units,
+			 u32 initial_units, acpi_completion * out_handle);
 
-acpi_status acpi_os_delete_semaphore(acpi_semaphore handle);
+acpi_status acpi_os_delete_completion(acpi_completion handle);
 
 acpi_status
-acpi_os_wait_semaphore(acpi_semaphore handle, u32 units, u16 timeout);
+acpi_os_wait_for_completion(acpi_completion handle, u32 units, u16 timeout);
 
-acpi_status acpi_os_signal_semaphore(acpi_semaphore handle, u32 units);
+acpi_status acpi_os_signal_complete(acpi_completion handle, u32 units);
 
 /*
  * Mutex primitives
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 4ea4f40..f580f12 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -316,7 +316,7 @@ struct uint32_struct {
 /* Synchronization objects */
 
 #define acpi_mutex                      void *
-#define acpi_semaphore                  void *
+#define acpi_completion                 void *
 
 /*
  * Acpi integer width. In ACPI version 1, integers are 32 bits.  In ACPI
diff --git a/include/linux/completion.h b/include/linux/completion.h
index d2961b6..00b1288 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -36,6 +36,25 @@ struct completion {
 # define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
 #endif
 
+/**
+ *	completion_done - Test to see if a completion has any waiters
+ *	@x:	completion structure
+ *
+ *	Returns: 0 if there are waiters (wait_for_completion() in progress)
+ *		 1 if there are no waiters.
+ *
+ */
+static inline bool completion_done(struct completion *x)
+{
+	int ret = 1;
+
+	spin_lock_irq(&x->wait.lock);
+	if (!x->done)
+		ret = 0;
+	spin_unlock_irq(&x->wait.lock);
+	return ret;
+}
+
 static inline void init_completion(struct completion *x)
 {
 	x->done = 0;
-- 
1.5.5.1.32.gba7d2


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux