mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
PM / Wakeup: Use rcu callbacks for better performance
Use rcu to free objects in wakeup_source_unregister(). These objects must be allocated through wakeup_source_register(). Replacing synchronize_rcu() with call_rcu() allows multiple calls to wakeup_source_unregister() to be combined into a single grace period. CRs-Fixed: 845110 Change-Id: Ib4002db042cf63abb28e6b3df6e3c70c97043bd9 Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
This commit is contained in:
parent
b38b86cfb7
commit
09919ab798
2 changed files with 32 additions and 2 deletions
|
@ -121,6 +121,15 @@ void wakeup_source_destroy(struct wakeup_source *ws)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(wakeup_source_destroy);
|
||||
|
||||
/**
|
||||
* wakeup_source_destroy_cb
|
||||
* defer processing until all rcu references have expired
|
||||
*/
|
||||
static void wakeup_source_destroy_cb(struct rcu_head *head)
|
||||
{
|
||||
wakeup_source_destroy(container_of(head, struct wakeup_source, rcu));
|
||||
}
|
||||
|
||||
/**
|
||||
* wakeup_source_add - Add given object to the list of wakeup sources.
|
||||
* @ws: Wakeup source object to add to the list.
|
||||
|
@ -157,6 +166,26 @@ void wakeup_source_remove(struct wakeup_source *ws)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(wakeup_source_remove);
|
||||
|
||||
/**
|
||||
* wakeup_source_remove_async - Remove given object from the wakeup sources
|
||||
* list.
|
||||
* @ws: Wakeup source object to remove from the list.
|
||||
*
|
||||
* Use only for wakeup source objects created with wakeup_source_create().
|
||||
* Memory for ws must be freed via rcu.
|
||||
*/
|
||||
static void wakeup_source_remove_async(struct wakeup_source *ws)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (WARN_ON(!ws))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&events_lock, flags);
|
||||
list_del_rcu(&ws->entry);
|
||||
spin_unlock_irqrestore(&events_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* wakeup_source_register - Create wakeup source and add it to the list.
|
||||
* @name: Name of the wakeup source to register.
|
||||
|
@ -180,8 +209,8 @@ EXPORT_SYMBOL_GPL(wakeup_source_register);
|
|||
void wakeup_source_unregister(struct wakeup_source *ws)
|
||||
{
|
||||
if (ws) {
|
||||
wakeup_source_remove(ws);
|
||||
wakeup_source_destroy(ws);
|
||||
wakeup_source_remove_async(ws);
|
||||
call_rcu(&ws->rcu, wakeup_source_destroy_cb);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wakeup_source_unregister);
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
struct wakeup_source {
|
||||
const char *name;
|
||||
struct list_head entry;
|
||||
struct rcu_head rcu;
|
||||
spinlock_t lock;
|
||||
struct timer_list timer;
|
||||
unsigned long timer_expires;
|
||||
|
|
Loading…
Reference in a new issue