From: Matthew Wilcox Date: Mon, 13 Feb 2017 15:19:22 +0000 (-0500) Subject: Convert semaphores to use waitlists X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fwlist;p=users%2Fwilly%2Fpagecache.git Convert semaphores to use waitlists Saves one pointer per semaphore, shrinking it from 24 bytes to 16 bytes. There aren't many semaphores left in the kernel, but there's no harm in having semaphores use the same scheme as mutexes and rwsems. Signed-off-by: Matthew Wilcox --- diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 57fb5f468ac20..cafbfe85d0181 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1198,7 +1198,7 @@ acpi_status acpi_os_delete_semaphore(acpi_handle handle) ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle)); - BUG_ON(!list_empty(&sem->wait_list)); + BUG_ON(!wlist_empty(&sem->wait_list)); kfree(sem); sem = NULL; diff --git a/include/linux/semaphore.h b/include/linux/semaphore.h index dc368b8ce215c..f83b6f6467367 100644 --- a/include/linux/semaphore.h +++ b/include/linux/semaphore.h @@ -16,14 +16,14 @@ struct semaphore { raw_spinlock_t lock; unsigned int count; - struct list_head wait_list; + struct wlist_head wait_list; }; #define __SEMAPHORE_INITIALIZER(name, n) \ { \ .lock = __RAW_SPIN_LOCK_UNLOCKED((name).lock), \ .count = n, \ - .wait_list = LIST_HEAD_INIT((name).wait_list), \ + .wait_list = WLIST_HEAD_INIT, \ } #define DEFINE_SEMAPHORE(name) \ diff --git a/kernel/locking/semaphore.c b/kernel/locking/semaphore.c index b8120abe594b8..56d5852e4c565 100644 --- a/kernel/locking/semaphore.c +++ b/kernel/locking/semaphore.c @@ -180,7 +180,7 @@ void up(struct semaphore *sem) unsigned long flags; raw_spin_lock_irqsave(&sem->lock, flags); - if (likely(list_empty(&sem->wait_list))) + if (likely(wlist_empty(&sem->wait_list))) sem->count++; else __up(sem); @@ -191,7 +191,7 @@ EXPORT_SYMBOL(up); /* Functions for the contended case */ struct semaphore_waiter { - struct list_head list; + struct wlist_node list; struct task_struct *task; bool up; }; @@ -207,7 +207,7 @@ static inline int __sched __down_common(struct semaphore *sem, long state, struct task_struct *task = current; struct semaphore_waiter waiter; - list_add_tail(&waiter.list, &sem->wait_list); + wlist_add(&sem->wait_list, &waiter.list); waiter.task = task; waiter.up = false; @@ -225,11 +225,11 @@ static inline int __sched __down_common(struct semaphore *sem, long state, } timed_out: - list_del(&waiter.list); + wlist_del(&sem->wait_list, &waiter.list); return -ETIME; interrupted: - list_del(&waiter.list); + wlist_del(&sem->wait_list, &waiter.list); return -EINTR; } @@ -255,9 +255,8 @@ static noinline int __sched __down_timeout(struct semaphore *sem, long timeout) static noinline void __sched __up(struct semaphore *sem) { - struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list, + struct semaphore_waiter *waiter = wlist_del_first_entry(&sem->wait_list, struct semaphore_waiter, list); - list_del(&waiter->list); waiter->up = true; wake_up_process(waiter->task); }