forked from Minki/linux
ipc: update semtimedop() to use hrtimer
semtimedop() should be converted to use hrtimer like it has been done for most of the system calls with timeouts. This system call already takes a struct timespec as an argument and can therefore provide finer granularity timed wait. Link: https://lkml.kernel.org/r/1651187881-2858-1-git-send-email-prakash.sangappa@oracle.com Signed-off-by: Prakash Sangappa <prakash.sangappa@oracle.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Davidlohr Bueso <dave@stgolabs.net> Reviewed-by: Manfred Spraul <manfred@colorfullife.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
0e90002965
commit
49c9dd0df6
23
ipc/sem.c
23
ipc/sem.c
@ -1993,7 +1993,9 @@ long __do_semtimedop(int semid, struct sembuf *sops,
|
||||
int max, locknum;
|
||||
bool undos = false, alter = false, dupsop = false;
|
||||
struct sem_queue queue;
|
||||
unsigned long dup = 0, jiffies_left = 0;
|
||||
unsigned long dup = 0;
|
||||
ktime_t expires, *exp = NULL;
|
||||
bool timed_out = false;
|
||||
|
||||
if (nsops < 1 || semid < 0)
|
||||
return -EINVAL;
|
||||
@ -2001,12 +2003,11 @@ long __do_semtimedop(int semid, struct sembuf *sops,
|
||||
return -E2BIG;
|
||||
|
||||
if (timeout) {
|
||||
if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 ||
|
||||
timeout->tv_nsec >= 1000000000L) {
|
||||
error = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
jiffies_left = timespec64_to_jiffies(timeout);
|
||||
if (!timespec64_valid(timeout))
|
||||
return -EINVAL;
|
||||
expires = ktime_add_safe(ktime_get(),
|
||||
timespec64_to_ktime(*timeout));
|
||||
exp = &expires;
|
||||
}
|
||||
|
||||
|
||||
@ -2164,10 +2165,8 @@ long __do_semtimedop(int semid, struct sembuf *sops,
|
||||
sem_unlock(sma, locknum);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (timeout)
|
||||
jiffies_left = schedule_timeout(jiffies_left);
|
||||
else
|
||||
schedule();
|
||||
timed_out = !schedule_hrtimeout_range(exp,
|
||||
current->timer_slack_ns, HRTIMER_MODE_ABS);
|
||||
|
||||
/*
|
||||
* fastpath: the semop has completed, either successfully or
|
||||
@ -2208,7 +2207,7 @@ long __do_semtimedop(int semid, struct sembuf *sops,
|
||||
/*
|
||||
* If an interrupt occurred we have to clean up the queue.
|
||||
*/
|
||||
if (timeout && jiffies_left == 0)
|
||||
if (timed_out)
|
||||
error = -EAGAIN;
|
||||
} while (error == -EINTR && !signal_pending(current)); /* spurious */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user