git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
trace: stop all recording to ring buffer on ftrace_dump
[safe/jmp/linux-2.6]
/
kernel
/
posix-timers.c
diff --git
a/kernel/posix-timers.c
b/kernel/posix-timers.c
index
95451bf
..
052ec4d
100644
(file)
--- a/
kernel/posix-timers.c
+++ b/
kernel/posix-timers.c
@@
-116,7
+116,7
@@
static DEFINE_SPINLOCK(idr_lock);
* must supply functions here, even if the function just returns
* ENOSYS. The standard POSIX timer management code assumes the
* following: 1.) The k_itimer struct (sched.h) is used for the
* must supply functions here, even if the function just returns
* ENOSYS. The standard POSIX timer management code assumes the
* following: 1.) The k_itimer struct (sched.h) is used for the
- * timer. 2.) The list, it_lock, it_clock, it_id and it_p
rocess
+ * timer. 2.) The list, it_lock, it_clock, it_id and it_p
id
* fields are not modified by timer code.
*
* At this time all functions EXCEPT clock_nanosleep can be
* fields are not modified by timer code.
*
* At this time all functions EXCEPT clock_nanosleep can be
@@
-197,6
+197,11
@@
static int common_timer_create(struct k_itimer *new_timer)
return 0;
}
return 0;
}
+static int no_timer_create(struct k_itimer *new_timer)
+{
+ return -EOPNOTSUPP;
+}
+
/*
* Return nonzero if we know a priori this clockid_t value is bogus.
*/
/*
* Return nonzero if we know a priori this clockid_t value is bogus.
*/
@@
-223,6
+228,15
@@
static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp)
}
/*
}
/*
+ * Get monotonic time for posix timers
+ */
+static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
+{
+ getrawmonotonic(tp);
+ return 0;
+}
+
+/*
* Initialize everything, well, just everything in Posix clocks/timers ;)
*/
static __init int init_posix_timers(void)
* Initialize everything, well, just everything in Posix clocks/timers ;)
*/
static __init int init_posix_timers(void)
@@
-235,9
+249,16
@@
static __init int init_posix_timers(void)
.clock_get = posix_ktime_get_ts,
.clock_set = do_posix_clock_nosettime,
};
.clock_get = posix_ktime_get_ts,
.clock_set = do_posix_clock_nosettime,
};
+ struct k_clock clock_monotonic_raw = {
+ .clock_getres = hrtimer_get_res,
+ .clock_get = posix_get_monotonic_raw,
+ .clock_set = do_posix_clock_nosettime,
+ .timer_create = no_timer_create,
+ };
register_posix_clock(CLOCK_REALTIME, &clock_realtime);
register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
register_posix_clock(CLOCK_REALTIME, &clock_realtime);
register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+ register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
posix_timers_cache = kmem_cache_create("posix_timers_cache",
sizeof (struct k_itimer), 0, SLAB_PANIC,
posix_timers_cache = kmem_cache_create("posix_timers_cache",
sizeof (struct k_itimer), 0, SLAB_PANIC,
@@
-298,7
+319,8
@@
void do_schedule_next_timer(struct siginfo *info)
int posix_timer_event(struct k_itimer *timr, int si_private)
{
int posix_timer_event(struct k_itimer *timr, int si_private)
{
- int shared, ret;
+ struct task_struct *task;
+ int shared, ret = -1;
/*
* FIXME: if ->sigq is queued we can race with
* dequeue_signal()->do_schedule_next_timer().
/*
* FIXME: if ->sigq is queued we can race with
* dequeue_signal()->do_schedule_next_timer().
@@
-312,8
+334,13
@@
int posix_timer_event(struct k_itimer *timr, int si_private)
*/
timr->sigq->info.si_sys_private = si_private;
*/
timr->sigq->info.si_sys_private = si_private;
- shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
- ret = send_sigqueue(timr->sigq, timr->it_process, shared);
+ rcu_read_lock();
+ task = pid_task(timr->it_pid, PIDTYPE_PID);
+ if (task) {
+ shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
+ ret = send_sigqueue(timr->sigq, task, shared);
+ }
+ rcu_read_unlock();
/* If we failed to send the signal the timer stops. */
return ret > 0;
}
/* If we failed to send the signal the timer stops. */
return ret > 0;
}
@@
-390,7
+417,7
@@
static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
return ret;
}
return ret;
}
-static struct
task_struct *
good_sigevent(sigevent_t * event)
+static struct
pid *
good_sigevent(sigevent_t * event)
{
struct task_struct *rtn = current->group_leader;
{
struct task_struct *rtn = current->group_leader;
@@
-404,7
+431,7
@@
static struct task_struct * good_sigevent(sigevent_t * event)
((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX)))
return NULL;
((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX)))
return NULL;
- return
rtn
;
+ return
task_pid(rtn)
;
}
void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock)
}
void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock)
@@
-427,7
+454,7
@@
static struct k_itimer * alloc_posix_timer(void)
return tmr;
if (unlikely(!(tmr->sigq = sigqueue_alloc()))) {
kmem_cache_free(posix_timers_cache, tmr);
return tmr;
if (unlikely(!(tmr->sigq = sigqueue_alloc()))) {
kmem_cache_free(posix_timers_cache, tmr);
-
tmr =
NULL;
+
return
NULL;
}
memset(&tmr->sigq->info, 0, sizeof(siginfo_t));
return tmr;
}
memset(&tmr->sigq->info, 0, sizeof(siginfo_t));
return tmr;
@@
-443,20
+470,19
@@
static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
idr_remove(&posix_timers_id, tmr->it_id);
spin_unlock_irqrestore(&idr_lock, flags);
}
idr_remove(&posix_timers_id, tmr->it_id);
spin_unlock_irqrestore(&idr_lock, flags);
}
+ put_pid(tmr->it_pid);
sigqueue_free(tmr->sigq);
kmem_cache_free(posix_timers_cache, tmr);
}
/* Create a POSIX.1b interval timer. */
sigqueue_free(tmr->sigq);
kmem_cache_free(posix_timers_cache, tmr);
}
/* Create a POSIX.1b interval timer. */
-asmlinkage long
-sys_timer_create(const clockid_t which_clock,
- struct sigevent __user *timer_event_spec,
- timer_t __user * created_timer_id)
+SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
+ struct sigevent __user *, timer_event_spec,
+ timer_t __user *, created_timer_id)
{
struct k_itimer *new_timer;
int error, new_timer_id;
{
struct k_itimer *new_timer;
int error, new_timer_id;
- struct task_struct *process;
sigevent_t event;
int it_id_set = IT_ID_NOT_SET;
sigevent_t event;
int it_id_set = IT_ID_NOT_SET;
@@
-510,11
+536,9
@@
sys_timer_create(const clockid_t which_clock,
goto out;
}
rcu_read_lock();
goto out;
}
rcu_read_lock();
- process = good_sigevent(&event);
- if (process)
- get_task_struct(process);
+ new_timer->it_pid = get_pid(good_sigevent(&event));
rcu_read_unlock();
rcu_read_unlock();
- if (!
process
) {
+ if (!
new_timer->it_pid
) {
error = -EINVAL;
goto out;
}
error = -EINVAL;
goto out;
}
@@
-522,8
+546,7
@@
sys_timer_create(const clockid_t which_clock,
event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = SIGALRM;
event.sigev_value.sival_int = new_timer->it_id;
event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = SIGALRM;
event.sigev_value.sival_int = new_timer->it_id;
- process = current->group_leader;
- get_task_struct(process);
+ new_timer->it_pid = get_pid(task_tgid(current));
}
new_timer->it_sigev_notify = event.sigev_notify;
}
new_timer->it_sigev_notify = event.sigev_notify;
@@
-533,7
+556,7
@@
sys_timer_create(const clockid_t which_clock,
new_timer->sigq->info.si_code = SI_TIMER;
spin_lock_irq(¤t->sighand->siglock);
new_timer->sigq->info.si_code = SI_TIMER;
spin_lock_irq(¤t->sighand->siglock);
- new_timer->it_
process = process
;
+ new_timer->it_
signal = current->signal
;
list_add(&new_timer->list, ¤t->signal->posix_timers);
spin_unlock_irq(¤t->sighand->siglock);
list_add(&new_timer->list, ¤t->signal->posix_timers);
spin_unlock_irq(¤t->sighand->siglock);
@@
-568,8
+591,7
@@
static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags)
timr = idr_find(&posix_timers_id, (int)timer_id);
if (timr) {
spin_lock(&timr->it_lock);
timr = idr_find(&posix_timers_id, (int)timer_id);
if (timr) {
spin_lock(&timr->it_lock);
- if (timr->it_process &&
- same_thread_group(timr->it_process, current)) {
+ if (timr->it_signal == current->signal) {
spin_unlock(&idr_lock);
return timr;
}
spin_unlock(&idr_lock);
return timr;
}
@@
-624,7
+646,7
@@
common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
(timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
(timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
- remaining = ktime_sub(
timer->expires
, now);
+ remaining = ktime_sub(
hrtimer_get_expires(timer)
, now);
/* Return 0 only, when the timer is expired and not pending */
if (remaining.tv64 <= 0) {
/*
/* Return 0 only, when the timer is expired and not pending */
if (remaining.tv64 <= 0) {
/*
@@
-638,8
+660,8
@@
common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
}
/* Get the time remaining on a POSIX.1b interval timer. */
}
/* Get the time remaining on a POSIX.1b interval timer. */
-asmlinkage long
-
sys_timer_gettime(timer_t timer_id, struct itimerspec __user *
setting)
+SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
+
struct itimerspec __user *,
setting)
{
struct k_itimer *timr;
struct itimerspec cur_setting;
{
struct k_itimer *timr;
struct itimerspec cur_setting;
@@
-668,8
+690,7
@@
sys_timer_gettime(timer_t timer_id, struct itimerspec __user *setting)
* the call back to do_schedule_next_timer(). So all we need to do is
* to pick up the frozen overrun.
*/
* the call back to do_schedule_next_timer(). So all we need to do is
* to pick up the frozen overrun.
*/
-asmlinkage long
-sys_timer_getoverrun(timer_t timer_id)
+SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
{
struct k_itimer *timr;
int overrun;
{
struct k_itimer *timr;
int overrun;
@@
-718,7
+739,7
@@
common_timer_set(struct k_itimer *timr, int flags,
hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
timr->it.real.timer.function = posix_timer_fn;
hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
timr->it.real.timer.function = posix_timer_fn;
-
timer->expires = timespec_to_ktime(new_setting->it_value
);
+
hrtimer_set_expires(timer, timespec_to_ktime(new_setting->it_value)
);
/* Convert interval */
timr->it.real.interval = timespec_to_ktime(new_setting->it_interval);
/* Convert interval */
timr->it.real.interval = timespec_to_ktime(new_setting->it_interval);
@@
-727,22
+748,19
@@
common_timer_set(struct k_itimer *timr, int flags,
if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
/* Setup correct expiry time for relative timers */
if (mode == HRTIMER_MODE_REL) {
if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
/* Setup correct expiry time for relative timers */
if (mode == HRTIMER_MODE_REL) {
- timer->expires =
- ktime_add_safe(timer->expires,
- timer->base->get_time());
+ hrtimer_add_expires(timer, timer->base->get_time());
}
return 0;
}
}
return 0;
}
- hrtimer_start
(timer, timer->expires
, mode);
+ hrtimer_start
_expires(timer
, mode);
return 0;
}
/* Set a POSIX.1b interval timer */
return 0;
}
/* Set a POSIX.1b interval timer */
-asmlinkage long
-sys_timer_settime(timer_t timer_id, int flags,
- const struct itimerspec __user *new_setting,
- struct itimerspec __user *old_setting)
+SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
+ const struct itimerspec __user *, new_setting,
+ struct itimerspec __user *, old_setting)
{
struct k_itimer *timr;
struct itimerspec new_spec, old_spec;
{
struct k_itimer *timr;
struct itimerspec new_spec, old_spec;
@@
-795,8
+813,7
@@
static inline int timer_delete_hook(struct k_itimer *timer)
}
/* Delete a POSIX.1b interval timer. */
}
/* Delete a POSIX.1b interval timer. */
-asmlinkage long
-sys_timer_delete(timer_t timer_id)
+SYSCALL_DEFINE1(timer_delete, timer_t, timer_id)
{
struct k_itimer *timer;
unsigned long flags;
{
struct k_itimer *timer;
unsigned long flags;
@@
-818,8
+835,7
@@
retry_delete:
* This keeps any tasks waiting on the spin lock from thinking
* they got something (see the lock code above).
*/
* This keeps any tasks waiting on the spin lock from thinking
* they got something (see the lock code above).
*/
- put_task_struct(timer->it_process);
- timer->it_process = NULL;
+ timer->it_signal = NULL;
unlock_timer(timer, flags);
release_posix_timer(timer, IT_ID_SET);
unlock_timer(timer, flags);
release_posix_timer(timer, IT_ID_SET);
@@
-845,8
+861,7
@@
retry_delete:
* This keeps any tasks waiting on the spin lock from thinking
* they got something (see the lock code above).
*/
* This keeps any tasks waiting on the spin lock from thinking
* they got something (see the lock code above).
*/
- put_task_struct(timer->it_process);
- timer->it_process = NULL;
+ timer->it_signal = NULL;
unlock_timer(timer, flags);
release_posix_timer(timer, IT_ID_SET);
unlock_timer(timer, flags);
release_posix_timer(timer, IT_ID_SET);
@@
-884,8
+899,8
@@
int do_posix_clock_nonanosleep(const clockid_t clock, int flags,
}
EXPORT_SYMBOL_GPL(do_posix_clock_nonanosleep);
}
EXPORT_SYMBOL_GPL(do_posix_clock_nonanosleep);
-
asmlinkage long sys_clock_settime(const clockid_t
which_clock,
-
const struct timespec __user *
tp)
+
SYSCALL_DEFINE2(clock_settime, const clockid_t,
which_clock,
+
const struct timespec __user *,
tp)
{
struct timespec new_tp;
{
struct timespec new_tp;
@@
-897,8
+912,8
@@
asmlinkage long sys_clock_settime(const clockid_t which_clock,
return CLOCK_DISPATCH(which_clock, clock_set, (which_clock, &new_tp));
}
return CLOCK_DISPATCH(which_clock, clock_set, (which_clock, &new_tp));
}
-asmlinkage long
-
sys_clock_gettime(const clockid_t which_clock, struct timespec __user *
tp)
+SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
+
struct timespec __user *,
tp)
{
struct timespec kernel_tp;
int error;
{
struct timespec kernel_tp;
int error;
@@
-914,8
+929,8
@@
sys_clock_gettime(const clockid_t which_clock, struct timespec __user *tp)
}
}
-asmlinkage long
-
sys_clock_getres(const clockid_t which_clock, struct timespec __user *
tp)
+SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
+
struct timespec __user *,
tp)
{
struct timespec rtn_tp;
int error;
{
struct timespec rtn_tp;
int error;
@@
-944,10
+959,9
@@
static int common_nsleep(const clockid_t which_clock, int flags,
which_clock);
}
which_clock);
}
-asmlinkage long
-sys_clock_nanosleep(const clockid_t which_clock, int flags,
- const struct timespec __user *rqtp,
- struct timespec __user *rmtp)
+SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
+ const struct timespec __user *, rqtp,
+ struct timespec __user *, rmtp)
{
struct timespec t;
{
struct timespec t;