Skip to content

Commit f8bd225

Browse files
Roman Zippeltorvalds
Roman Zippel
authored andcommitted
remove div_long_long_rem
x86 is the only arch right now, which provides an optimized for div_long_long_rem and it has the downside that one has to be very careful that the divide doesn't overflow. The API is a little akward, as the arguments for the unsigned divide are signed. The signed version also doesn't handle a negative divisor and produces worse code on 64bit archs. There is little incentive to keep this API alive, so this converts the few users to the new API. Signed-off-by: Roman Zippel <zippel@linux-m68k.org> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: john stultz <johnstul@us.ibm.com> Cc: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 6f6d6a1 commit f8bd225

File tree

10 files changed

+44
-110
lines changed

10 files changed

+44
-110
lines changed

Diff for: arch/mips/kernel/binfmt_elfn32.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
5454
#include <linux/module.h>
5555
#include <linux/elfcore.h>
5656
#include <linux/compat.h>
57+
#include <linux/math64.h>
5758

5859
#define elf_prstatus elf_prstatus32
5960
struct elf_prstatus32
@@ -102,8 +103,8 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
102103
* one divide.
103104
*/
104105
u64 nsec = (u64)jiffies * TICK_NSEC;
105-
long rem;
106-
value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
106+
u32 rem;
107+
value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
107108
value->tv_usec = rem / NSEC_PER_USEC;
108109
}
109110

Diff for: arch/mips/kernel/binfmt_elfo32.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
5656
#include <linux/module.h>
5757
#include <linux/elfcore.h>
5858
#include <linux/compat.h>
59+
#include <linux/math64.h>
5960

6061
#define elf_prstatus elf_prstatus32
6162
struct elf_prstatus32
@@ -104,8 +105,8 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
104105
* one divide.
105106
*/
106107
u64 nsec = (u64)jiffies * TICK_NSEC;
107-
long rem;
108-
value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
108+
u32 rem;
109+
value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
109110
value->tv_usec = rem / NSEC_PER_USEC;
110111
}
111112

Diff for: drivers/char/mmtimer.c

+11-13
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include <linux/miscdevice.h>
3131
#include <linux/posix-timers.h>
3232
#include <linux/interrupt.h>
33+
#include <linux/time.h>
34+
#include <linux/math64.h>
3335

3436
#include <asm/uaccess.h>
3537
#include <asm/sn/addrs.h>
@@ -472,20 +474,20 @@ static int sgi_clock_get(clockid_t clockid, struct timespec *tp)
472474

473475
nsec = rtc_time() * sgi_clock_period
474476
+ sgi_clock_offset.tv_nsec;
475-
tp->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tp->tv_nsec)
476-
+ sgi_clock_offset.tv_sec;
477+
*tp = ns_to_timespec(nsec);
478+
tp->tv_sec += sgi_clock_offset.tv_sec;
477479
return 0;
478480
};
479481

480482
static int sgi_clock_set(clockid_t clockid, struct timespec *tp)
481483
{
482484

483485
u64 nsec;
484-
u64 rem;
486+
u32 rem;
485487

486488
nsec = rtc_time() * sgi_clock_period;
487489

488-
sgi_clock_offset.tv_sec = tp->tv_sec - div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
490+
sgi_clock_offset.tv_sec = tp->tv_sec - div_u64_rem(nsec, NSEC_PER_SEC, &rem);
489491

490492
if (rem <= tp->tv_nsec)
491493
sgi_clock_offset.tv_nsec = tp->tv_sec - rem;
@@ -644,9 +646,6 @@ static int sgi_timer_del(struct k_itimer *timr)
644646
return 0;
645647
}
646648

647-
#define timespec_to_ns(x) ((x).tv_nsec + (x).tv_sec * NSEC_PER_SEC)
648-
#define ns_to_timespec(ts, nsec) (ts).tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &(ts).tv_nsec)
649-
650649
/* Assumption: it_lock is already held with irq's disabled */
651650
static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
652651
{
@@ -659,9 +658,8 @@ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
659658
return;
660659
}
661660

662-
ns_to_timespec(cur_setting->it_interval, timr->it.mmtimer.incr * sgi_clock_period);
663-
ns_to_timespec(cur_setting->it_value, (timr->it.mmtimer.expires - rtc_time())* sgi_clock_period);
664-
return;
661+
cur_setting->it_interval = ns_to_timespec(timr->it.mmtimer.incr * sgi_clock_period);
662+
cur_setting->it_value = ns_to_timespec((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period);
665663
}
666664

667665

@@ -679,8 +677,8 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
679677
sgi_timer_get(timr, old_setting);
680678

681679
sgi_timer_del(timr);
682-
when = timespec_to_ns(new_setting->it_value);
683-
period = timespec_to_ns(new_setting->it_interval);
680+
when = timespec_to_ns(&new_setting->it_value);
681+
period = timespec_to_ns(&new_setting->it_interval);
684682

685683
if (when == 0)
686684
/* Clear timer */
@@ -695,7 +693,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
695693
unsigned long now;
696694

697695
getnstimeofday(&n);
698-
now = timespec_to_ns(n);
696+
now = timespec_to_ns(&n);
699697
if (when > now)
700698
when -= now;
701699
else

Diff for: include/asm-x86/div64.h

-18
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,6 @@
3333
__mod; \
3434
})
3535

36-
/*
37-
* (long)X = ((long long)divs) / (long)div
38-
* (long)rem = ((long long)divs) % (long)div
39-
*
40-
* Warning, this will do an exception if X overflows.
41-
*/
42-
#define div_long_long_rem(a, b, c) div_ll_X_l_rem(a, b, c)
43-
44-
static inline long div_ll_X_l_rem(long long divs, long div, long *rem)
45-
{
46-
long dum2;
47-
asm("divl %2":"=a"(dum2), "=d"(*rem)
48-
: "rm"(div), "A"(divs));
49-
50-
return dum2;
51-
52-
}
53-
5436
static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
5537
{
5638
union {

Diff for: include/linux/calc64.h

-49
This file was deleted.

Diff for: include/linux/jiffies.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef _LINUX_JIFFIES_H
22
#define _LINUX_JIFFIES_H
33

4-
#include <linux/calc64.h>
4+
#include <linux/math64.h>
55
#include <linux/kernel.h>
66
#include <linux/types.h>
77
#include <linux/time.h>

Diff for: kernel/posix-cpu-timers.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
#include <linux/sched.h>
66
#include <linux/posix-timers.h>
7-
#include <asm/uaccess.h>
87
#include <linux/errno.h>
8+
#include <linux/math64.h>
9+
#include <asm/uaccess.h>
910

1011
static int check_clock(const clockid_t which_clock)
1112
{
@@ -47,12 +48,10 @@ static void sample_to_timespec(const clockid_t which_clock,
4748
union cpu_time_count cpu,
4849
struct timespec *tp)
4950
{
50-
if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
51-
tp->tv_sec = div_long_long_rem(cpu.sched,
52-
NSEC_PER_SEC, &tp->tv_nsec);
53-
} else {
51+
if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED)
52+
*tp = ns_to_timespec(cpu.sched);
53+
else
5454
cputime_to_timespec(cpu.cpu, tp);
55-
}
5655
}
5756

5857
static inline int cpu_time_before(const clockid_t which_clock,

Diff for: kernel/time.c

+15-10
Original file line numberDiff line numberDiff line change
@@ -392,13 +392,17 @@ EXPORT_SYMBOL(set_normalized_timespec);
392392
struct timespec ns_to_timespec(const s64 nsec)
393393
{
394394
struct timespec ts;
395+
s32 rem;
395396

396397
if (!nsec)
397398
return (struct timespec) {0, 0};
398399

399-
ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC, &ts.tv_nsec);
400-
if (unlikely(nsec < 0))
401-
set_normalized_timespec(&ts, ts.tv_sec, ts.tv_nsec);
400+
ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
401+
if (unlikely(rem < 0)) {
402+
ts.tv_sec--;
403+
rem += NSEC_PER_SEC;
404+
}
405+
ts.tv_nsec = rem;
402406

403407
return ts;
404408
}
@@ -528,8 +532,10 @@ jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
528532
* Convert jiffies to nanoseconds and separate with
529533
* one divide.
530534
*/
531-
u64 nsec = (u64)jiffies * TICK_NSEC;
532-
value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_nsec);
535+
u32 rem;
536+
value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
537+
NSEC_PER_SEC, &rem);
538+
value->tv_nsec = rem;
533539
}
534540
EXPORT_SYMBOL(jiffies_to_timespec);
535541

@@ -567,12 +573,11 @@ void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)
567573
* Convert jiffies to nanoseconds and separate with
568574
* one divide.
569575
*/
570-
u64 nsec = (u64)jiffies * TICK_NSEC;
571-
long tv_usec;
576+
u32 rem;
572577

573-
value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tv_usec);
574-
tv_usec /= NSEC_PER_USEC;
575-
value->tv_usec = tv_usec;
578+
value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
579+
NSEC_PER_SEC, &rem);
580+
value->tv_usec = rem / NSEC_PER_USEC;
576581
}
577582
EXPORT_SYMBOL(jiffies_to_timeval);
578583

Diff for: kernel/time/ntp.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ static inline void notify_cmos_timer(void) { }
234234
*/
235235
int do_adjtimex(struct timex *txc)
236236
{
237-
long mtemp, save_adjust, rem;
237+
long mtemp, save_adjust;
238238
s64 freq_adj;
239239
int result;
240240

@@ -345,9 +345,7 @@ int do_adjtimex(struct timex *txc)
345345
freq_adj += time_freq;
346346
freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC);
347347
time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC);
348-
time_offset = div_long_long_rem_signed(time_offset,
349-
NTP_INTERVAL_FREQ,
350-
&rem);
348+
time_offset = div_s64(time_offset, NTP_INTERVAL_FREQ);
351349
time_offset <<= SHIFT_UPDATE;
352350
} /* STA_PLL */
353351
} /* txc->modes & ADJ_OFFSET */

Diff for: mm/slub.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/debugobjects.h>
2323
#include <linux/kallsyms.h>
2424
#include <linux/memory.h>
25+
#include <linux/math64.h>
2526

2627
/*
2728
* Lock order:
@@ -3621,12 +3622,10 @@ static int list_locations(struct kmem_cache *s, char *buf,
36213622
len += sprintf(buf + len, "<not-available>");
36223623

36233624
if (l->sum_time != l->min_time) {
3624-
unsigned long remainder;
3625-
36263625
len += sprintf(buf + len, " age=%ld/%ld/%ld",
3627-
l->min_time,
3628-
div_long_long_rem(l->sum_time, l->count, &remainder),
3629-
l->max_time);
3626+
l->min_time,
3627+
(long)div_u64(l->sum_time, l->count),
3628+
l->max_time);
36303629
} else
36313630
len += sprintf(buf + len, " age=%ld",
36323631
l->min_time);

0 commit comments

Comments
 (0)