mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 22:24:11 +08:00
ipc/sem.c: sem optimise undo list search
Around a month ago, there was some discussion about an improvement of the sysv sem algorithm: Most (at least: some important) users only use simple semaphore operations, therefore it's worthwile to optimize this use case. This patch: Move last looked up sem_undo struct to the head of the task's undo list. Attempt to move common entries to the front of the list so search time is reduced. This reduces lookup_undo on oprofile of problematic SAP workload by 30% (see patch 4 for a description of SAP workload). Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Manfred Spraul <manfred@colorfullife.com> Cc: Pierre Peiffer <peifferp@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
7d6feeb287
commit
bf17bb7177
26
ipc/sem.c
26
ipc/sem.c
@ -962,17 +962,31 @@ static inline int get_undo_list(struct sem_undo_list **undo_listp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sem_undo *lookup_undo(struct sem_undo_list *ulp, int semid)
|
static struct sem_undo *__lookup_undo(struct sem_undo_list *ulp, int semid)
|
||||||
{
|
{
|
||||||
struct sem_undo *walk;
|
struct sem_undo *un;
|
||||||
|
|
||||||
list_for_each_entry_rcu(walk, &ulp->list_proc, list_proc) {
|
list_for_each_entry_rcu(un, &ulp->list_proc, list_proc) {
|
||||||
if (walk->semid == semid)
|
if (un->semid == semid)
|
||||||
return walk;
|
return un;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct sem_undo *lookup_undo(struct sem_undo_list *ulp, int semid)
|
||||||
|
{
|
||||||
|
struct sem_undo *un;
|
||||||
|
|
||||||
|
assert_spin_locked(&ulp->lock);
|
||||||
|
|
||||||
|
un = __lookup_undo(ulp, semid);
|
||||||
|
if (un) {
|
||||||
|
list_del_rcu(&un->list_proc);
|
||||||
|
list_add_rcu(&un->list_proc, &ulp->list_proc);
|
||||||
|
}
|
||||||
|
return un;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find_alloc_undo - Lookup (and if not present create) undo array
|
* find_alloc_undo - Lookup (and if not present create) undo array
|
||||||
* @ns: namespace
|
* @ns: namespace
|
||||||
@ -1308,7 +1322,7 @@ void exit_sem(struct task_struct *tsk)
|
|||||||
if (IS_ERR(sma))
|
if (IS_ERR(sma))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
un = lookup_undo(ulp, semid);
|
un = __lookup_undo(ulp, semid);
|
||||||
if (un == NULL) {
|
if (un == NULL) {
|
||||||
/* exit_sem raced with IPC_RMID+semget() that created
|
/* exit_sem raced with IPC_RMID+semget() that created
|
||||||
* exactly the same semid. Nothing to do.
|
* exactly the same semid. Nothing to do.
|
||||||
|
Loading…
Reference in New Issue
Block a user