Commit 1536340e authored by Linus Torvalds's avatar Linus Torvalds

Merge branches 'locking-urgent-for-linus' and 'timers-urgent-for-linus' of...

Merge branches 'locking-urgent-for-linus' and 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull futex and timer fixes from Thomas Gleixner:
 "A oneliner bugfix for the jinxed futex code:

   - Drop hash bucket lock in the error exit path.  I really could slap
     myself for intruducing that bug while fixing all the other horror
     in that code three month ago ...

  and the timer department is not too proud about the following fixes:

   - Deal with a long standing rounding bug in the timeval to jiffies
     conversion.  It's a real issue and this fix fell through the cracks
     for quite some time.

   - Another round of alarmtimer fixes.  Finally this code gets used
     more widely and the subtle issues hidden for quite some time are
     noticed and fixed.  Nothing really exciting, just the itty bitty
     details which bite the serious users here and there"

* 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  futex: Unlock hb->lock in futex_wait_requeue_pi() error path

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  alarmtimer: Lock k_itimer during timer callback
  alarmtimer: Do not signal SIGEV_NONE timers
  alarmtimer: Return relative times in timer_gettime
  jiffies: Fix timeval conversion to jiffies
...@@ -258,23 +258,11 @@ extern unsigned long preset_lpj; ...@@ -258,23 +258,11 @@ extern unsigned long preset_lpj;
#define SEC_JIFFIE_SC (32 - SHIFT_HZ) #define SEC_JIFFIE_SC (32 - SHIFT_HZ)
#endif #endif
#define NSEC_JIFFIE_SC (SEC_JIFFIE_SC + 29) #define NSEC_JIFFIE_SC (SEC_JIFFIE_SC + 29)
#define USEC_JIFFIE_SC (SEC_JIFFIE_SC + 19)
#define SEC_CONVERSION ((unsigned long)((((u64)NSEC_PER_SEC << SEC_JIFFIE_SC) +\ #define SEC_CONVERSION ((unsigned long)((((u64)NSEC_PER_SEC << SEC_JIFFIE_SC) +\
TICK_NSEC -1) / (u64)TICK_NSEC)) TICK_NSEC -1) / (u64)TICK_NSEC))
#define NSEC_CONVERSION ((unsigned long)((((u64)1 << NSEC_JIFFIE_SC) +\ #define NSEC_CONVERSION ((unsigned long)((((u64)1 << NSEC_JIFFIE_SC) +\
TICK_NSEC -1) / (u64)TICK_NSEC)) TICK_NSEC -1) / (u64)TICK_NSEC))
#define USEC_CONVERSION \
((unsigned long)((((u64)NSEC_PER_USEC << USEC_JIFFIE_SC) +\
TICK_NSEC -1) / (u64)TICK_NSEC))
/*
* USEC_ROUND is used in the timeval to jiffie conversion. See there
* for more details. It is the scaled resolution rounding value. Note
* that it is a 64-bit value. Since, when it is applied, we are already
* in jiffies (albit scaled), it is nothing but the bits we will shift
* off.
*/
#define USEC_ROUND (u64)(((u64)1 << USEC_JIFFIE_SC) - 1)
/* /*
* The maximum jiffie value is (MAX_INT >> 1). Here we translate that * The maximum jiffie value is (MAX_INT >> 1). Here we translate that
* into seconds. The 64-bit case will overflow if we are not careful, * into seconds. The 64-bit case will overflow if we are not careful,
......
...@@ -2592,6 +2592,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, ...@@ -2592,6 +2592,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
* shared futexes. We need to compare the keys: * shared futexes. We need to compare the keys:
*/ */
if (match_futex(&q.key, &key2)) { if (match_futex(&q.key, &key2)) {
queue_unlock(hb);
ret = -EINVAL; ret = -EINVAL;
goto out_put_keys; goto out_put_keys;
} }
......
...@@ -464,18 +464,26 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid) ...@@ -464,18 +464,26 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid)
static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
ktime_t now) ktime_t now)
{ {
unsigned long flags;
struct k_itimer *ptr = container_of(alarm, struct k_itimer, struct k_itimer *ptr = container_of(alarm, struct k_itimer,
it.alarm.alarmtimer); it.alarm.alarmtimer);
if (posix_timer_event(ptr, 0) != 0) enum alarmtimer_restart result = ALARMTIMER_NORESTART;
ptr->it_overrun++;
spin_lock_irqsave(&ptr->it_lock, flags);
if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
if (posix_timer_event(ptr, 0) != 0)
ptr->it_overrun++;
}
/* Re-add periodic timers */ /* Re-add periodic timers */
if (ptr->it.alarm.interval.tv64) { if (ptr->it.alarm.interval.tv64) {
ptr->it_overrun += alarm_forward(alarm, now, ptr->it_overrun += alarm_forward(alarm, now,
ptr->it.alarm.interval); ptr->it.alarm.interval);
return ALARMTIMER_RESTART; result = ALARMTIMER_RESTART;
} }
return ALARMTIMER_NORESTART; spin_unlock_irqrestore(&ptr->it_lock, flags);
return result;
} }
/** /**
...@@ -541,18 +549,22 @@ static int alarm_timer_create(struct k_itimer *new_timer) ...@@ -541,18 +549,22 @@ static int alarm_timer_create(struct k_itimer *new_timer)
* @new_timer: k_itimer pointer * @new_timer: k_itimer pointer
* @cur_setting: itimerspec data to fill * @cur_setting: itimerspec data to fill
* *
* Copies the itimerspec data out from the k_itimer * Copies out the current itimerspec data
*/ */
static void alarm_timer_get(struct k_itimer *timr, static void alarm_timer_get(struct k_itimer *timr,
struct itimerspec *cur_setting) struct itimerspec *cur_setting)
{ {
memset(cur_setting, 0, sizeof(struct itimerspec)); ktime_t relative_expiry_time =
alarm_expires_remaining(&(timr->it.alarm.alarmtimer));
if (ktime_to_ns(relative_expiry_time) > 0) {
cur_setting->it_value = ktime_to_timespec(relative_expiry_time);
} else {
cur_setting->it_value.tv_sec = 0;
cur_setting->it_value.tv_nsec = 0;
}
cur_setting->it_interval = cur_setting->it_interval = ktime_to_timespec(timr->it.alarm.interval);
ktime_to_timespec(timr->it.alarm.interval);
cur_setting->it_value =
ktime_to_timespec(timr->it.alarm.alarmtimer.node.expires);
return;
} }
/** /**
......
...@@ -559,17 +559,20 @@ EXPORT_SYMBOL(usecs_to_jiffies); ...@@ -559,17 +559,20 @@ EXPORT_SYMBOL(usecs_to_jiffies);
* that a remainder subtract here would not do the right thing as the * that a remainder subtract here would not do the right thing as the
* resolution values don't fall on second boundries. I.e. the line: * resolution values don't fall on second boundries. I.e. the line:
* nsec -= nsec % TICK_NSEC; is NOT a correct resolution rounding. * nsec -= nsec % TICK_NSEC; is NOT a correct resolution rounding.
* Note that due to the small error in the multiplier here, this
* rounding is incorrect for sufficiently large values of tv_nsec, but
* well formed timespecs should have tv_nsec < NSEC_PER_SEC, so we're
* OK.
* *
* Rather, we just shift the bits off the right. * Rather, we just shift the bits off the right.
* *
* The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
* value to a scaled second value. * value to a scaled second value.
*/ */
unsigned long static unsigned long
timespec_to_jiffies(const struct timespec *value) __timespec_to_jiffies(unsigned long sec, long nsec)
{ {
unsigned long sec = value->tv_sec; nsec = nsec + TICK_NSEC - 1;
long nsec = value->tv_nsec + TICK_NSEC - 1;
if (sec >= MAX_SEC_IN_JIFFIES){ if (sec >= MAX_SEC_IN_JIFFIES){
sec = MAX_SEC_IN_JIFFIES; sec = MAX_SEC_IN_JIFFIES;
...@@ -580,6 +583,13 @@ timespec_to_jiffies(const struct timespec *value) ...@@ -580,6 +583,13 @@ timespec_to_jiffies(const struct timespec *value)
(NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
} }
unsigned long
timespec_to_jiffies(const struct timespec *value)
{
return __timespec_to_jiffies(value->tv_sec, value->tv_nsec);
}
EXPORT_SYMBOL(timespec_to_jiffies); EXPORT_SYMBOL(timespec_to_jiffies);
void void
...@@ -596,31 +606,27 @@ jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) ...@@ -596,31 +606,27 @@ jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
} }
EXPORT_SYMBOL(jiffies_to_timespec); EXPORT_SYMBOL(jiffies_to_timespec);
/* Same for "timeval" /*
* * We could use a similar algorithm to timespec_to_jiffies (with a
* Well, almost. The problem here is that the real system resolution is * different multiplier for usec instead of nsec). But this has a
* in nanoseconds and the value being converted is in micro seconds. * problem with rounding: we can't exactly add TICK_NSEC - 1 to the
* Also for some machines (those that use HZ = 1024, in-particular), * usec value, since it's not necessarily integral.
* there is a LARGE error in the tick size in microseconds. *
* We could instead round in the intermediate scaled representation
* The solution we use is to do the rounding AFTER we convert the * (i.e. in units of 1/2^(large scale) jiffies) but that's also
* microsecond part. Thus the USEC_ROUND, the bits to be shifted off. * perilous: the scaling introduces a small positive error, which
* Instruction wise, this should cost only an additional add with carry * combined with a division-rounding-upward (i.e. adding 2^(scale) - 1
* instruction above the way it was done above. * units to the intermediate before shifting) leads to accidental
* overflow and overestimates.
*
* At the cost of one additional multiplication by a constant, just
* use the timespec implementation.
*/ */
unsigned long unsigned long
timeval_to_jiffies(const struct timeval *value) timeval_to_jiffies(const struct timeval *value)
{ {
unsigned long sec = value->tv_sec; return __timespec_to_jiffies(value->tv_sec,
long usec = value->tv_usec; value->tv_usec * NSEC_PER_USEC);
if (sec >= MAX_SEC_IN_JIFFIES){
sec = MAX_SEC_IN_JIFFIES;
usec = 0;
}
return (((u64)sec * SEC_CONVERSION) +
(((u64)usec * USEC_CONVERSION + USEC_ROUND) >>
(USEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
} }
EXPORT_SYMBOL(timeval_to_jiffies); EXPORT_SYMBOL(timeval_to_jiffies);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment