Mailing List Archive

[PATCH RFC 04/25] Replace "/" operand with div64
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

ARM does not have a division operator: division has to be implemented
in software.
On x86 and ia64 div64 falls back to a do_div based implementation.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
---
xen/common/keyhandler.c | 4 +-
xen/common/lib.c | 9 ++++--
xen/common/sched_credit.c | 7 +++--
xen/common/sched_credit2.c | 5 ++-
xen/common/sched_sedf.c | 30 ++++++++++++------------
xen/common/timer.c | 7 ++++-
xen/include/asm-ia64/linux/asm-generic/div64.h | 6 ++++
xen/include/asm-x86/div64.h | 6 ++++
8 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
index 6071f09..1700b8a 100644
--- a/xen/common/keyhandler.c
+++ b/xen/common/keyhandler.c
@@ -392,10 +392,10 @@ static void read_clocks(unsigned char key)
count++;
printk("Synced stime skew: max=%"PRIu64"ns avg=%"PRIu64"ns "
"samples=%"PRIu32" current=%"PRIu64"ns\n",
- maxdif_stime, sumdif_stime/count, count, dif_stime);
+ maxdif_stime, div64(sumdif_stime, count), count, dif_stime);
printk("Synced cycles skew: max=%"PRIu64" avg=%"PRIu64" "
"samples=%"PRIu32" current=%"PRIu64"\n",
- maxdif_cycles, sumdif_cycles/count, count, dif_cycles);
+ maxdif_cycles, div64(sumdif_cycles, count), count, dif_cycles);
}

static struct keyhandler read_clocks_keyhandler = {
diff --git a/xen/common/lib.c b/xen/common/lib.c
index 4ae637c..2b543b0 100644
--- a/xen/common/lib.c
+++ b/xen/common/lib.c
@@ -3,6 +3,7 @@
#include <xen/lib.h>
#include <xen/types.h>
#include <asm/byteorder.h>
+#include <asm/div64.h>

/* for ctype.h */
const unsigned char _ctype[] = {
@@ -418,14 +419,16 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
#endif
} l;
} u, res;
- uint64_t rl, rh;
+ uint64_t rl, rh, t;

u.ll = a;
rl = (uint64_t)u.l.low * (uint64_t)b;
rh = (uint64_t)u.l.high * (uint64_t)b;
rh += (rl >> 32);
- res.l.high = rh / c;
- res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+
+ t = do_div(rh, c);
+ res.l.high = rh;
+ res.l.low = div64(((t << 32) + (rl & 0xffffffff)), c);
return res.ll;
#endif
}
diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c
index 4fa6140..02f77ee 100644
--- a/xen/common/sched_credit.c
+++ b/xen/common/sched_credit.c
@@ -22,6 +22,7 @@
#include <asm/atomic.h>
#include <xen/errno.h>
#include <xen/keyhandler.h>
+#include <asm/div64.h>

/*
* CSCHED_STATS
@@ -241,9 +242,9 @@ static void burn_credits(struct csched_vcpu *svc, s_time_t now)
if ( (delta = now - svc->start_time) <= 0 )
return;

- credits = (delta*CSCHED_CREDITS_PER_MSEC + MILLISECS(1)/2) / MILLISECS(1);
+ credits = div64((delta*CSCHED_CREDITS_PER_MSEC + MILLISECS(1)/2), MILLISECS(1));
atomic_sub(credits, &svc->credit);
- svc->start_time += (credits * MILLISECS(1)) / CSCHED_CREDITS_PER_MSEC;
+ svc->start_time += div64(credits * MILLISECS(1), CSCHED_CREDITS_PER_MSEC);
}

static bool_t __read_mostly opt_tickle_one_idle = 1;
@@ -1570,7 +1571,7 @@ static void csched_tick_resume(const struct scheduler *ops, unsigned int cpu)
prv = CSCHED_PRIV(ops);

set_timer(&spc->ticker, now + MICROSECS(prv->tick_period_us)
- - now % MICROSECS(prv->tick_period_us) );
+ - do_div(now, MILLISECS(prv->tick_period_us)) );
}

static struct csched_private _csched_priv;
diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
index 73f7138..46f48db 100644
--- a/xen/common/sched_credit2.c
+++ b/xen/common/sched_credit2.c
@@ -25,6 +25,7 @@
#include <xen/errno.h>
#include <xen/trace.h>
#include <xen/cpu.h>
+#include <asm/div64.h>

#define d2printk(x...)
//#define d2printk printk
@@ -273,12 +274,12 @@ struct csched_dom {
*/
static s_time_t t2c(struct csched_runqueue_data *rqd, s_time_t time, struct csched_vcpu *svc)
{
- return time * rqd->max_weight / svc->weight;
+ return div64(time * rqd->max_weight, svc->weight);
}

static s_time_t c2t(struct csched_runqueue_data *rqd, s_time_t credit, struct csched_vcpu *svc)
{
- return credit * svc->weight / rqd->max_weight;
+ return div64(credit * svc->weight, rqd->max_weight);
}

/*
diff --git a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c
index 8bff90c..e8eab31 100644
--- a/xen/common/sched_sedf.c
+++ b/xen/common/sched_sedf.c
@@ -12,6 +12,7 @@
#include <xen/softirq.h>
#include <xen/time.h>
#include <xen/errno.h>
+#include <asm/div64.h>

/*verbosity settings*/
#define SEDFLEVEL 0
@@ -127,7 +128,7 @@ struct sedf_cpu_info {

#define PERIOD_BEGIN(inf) ((inf)->deadl_abs - (inf)->period)

-#define DIV_UP(x,y) (((x) + (y) - 1) / y)
+#define DIV_UP(x,y) div64((x) + (y) - 1, y)

#define extra_runs(inf) ((inf->status) & 6)
#define extra_get_cur_q(inf) (((inf->status & 6) >> 1)-1)
@@ -678,8 +679,7 @@ static void desched_extra_dom(s_time_t now, struct vcpu *d)
utilization and is used somewhat incremental!*/
if ( !inf->extraweight )
/*NB: use fixed point arithmetic with 10 bits*/
- inf->score[EXTRA_UTIL_Q] = (inf->period << 10) /
- inf->slice;
+ inf->score[EXTRA_UTIL_Q] = div64(inf->period << 10, inf->slice);
else
/*conversion between realtime utilisation and extrawieght:
full (ie 100%) utilization is equivalent to 128 extraweight*/
@@ -996,8 +996,8 @@ static void unblock_short_extra_support(

if ( inf->short_block_lost_tot )
{
- inf->score[0] = (inf->period << 10) /
- inf->short_block_lost_tot;
+ inf->score[0] = div64(inf->period << 10,
+ inf->short_block_lost_tot);
#ifdef SEDF_STATS
inf->pen_extra_blocks++;
#endif
@@ -1224,8 +1224,8 @@ static void sedf_dump_domain(struct vcpu *d)

#ifdef SEDF_STATS
if ( EDOM_INFO(d)->block_time_tot != 0 )
- printk(" pen=%"PRIu64"%%", (EDOM_INFO(d)->penalty_time_tot * 100) /
- EDOM_INFO(d)->block_time_tot);
+ printk(" pen=%"PRIu64"%%",
+ div64(EDOM_INFO(d)->penalty_time_tot * 100, EDOM_INFO(d)->block_time_tot));
if ( EDOM_INFO(d)->block_tot != 0 )
printk("\n blks=%u sh=%u (%u%%) (shc=%u (%u%%) shex=%i "\
"shexsl=%i) l=%u (%u%%) avg: b=%"PRIu64" p=%"PRIu64"",
@@ -1237,8 +1237,8 @@ static void sedf_dump_domain(struct vcpu *d)
EDOM_INFO(d)->pen_extra_slices,
EDOM_INFO(d)->long_block_tot,
(EDOM_INFO(d)->long_block_tot * 100) / EDOM_INFO(d)->block_tot,
- (EDOM_INFO(d)->block_time_tot) / EDOM_INFO(d)->block_tot,
- (EDOM_INFO(d)->penalty_time_tot) / EDOM_INFO(d)->block_tot);
+ div64(EDOM_INFO(d)->block_time_tot, EDOM_INFO(d)->block_tot),
+ div64(EDOM_INFO(d)->penalty_time_tot, EDOM_INFO(d)->block_tot));
#endif
printk("\n");
}
@@ -1357,9 +1357,9 @@ static int sedf_adjust_weights(struct cpupool *c, struct xen_domctl_scheduler_op
/*check for overflows*/
ASSERT((WEIGHT_PERIOD < ULONG_MAX)
&& (EDOM_INFO(p)->slice_orig < ULONG_MAX));
- sumt[cpu] +=
- (WEIGHT_PERIOD * EDOM_INFO(p)->slice_orig) /
- EDOM_INFO(p)->period_orig;
+ sumt[cpu] += div64(
+ WEIGHT_PERIOD * EDOM_INFO(p)->slice_orig,
+ EDOM_INFO(p)->period_orig);
}
}
}
@@ -1378,9 +1378,9 @@ static int sedf_adjust_weights(struct cpupool *c, struct xen_domctl_scheduler_op
EDOM_INFO(p)->period_orig =
EDOM_INFO(p)->period = WEIGHT_PERIOD;
EDOM_INFO(p)->slice_orig =
- EDOM_INFO(p)->slice =
- (EDOM_INFO(p)->weight *
- (WEIGHT_PERIOD - WEIGHT_SAFETY - sumt[cpu])) / sumw[cpu];
+ EDOM_INFO(p)->slice = div64(
+ EDOM_INFO(p)->weight * (WEIGHT_PERIOD - WEIGHT_SAFETY - sumt[cpu]),
+ sumw[cpu]);
}
}
}
diff --git a/xen/common/timer.c b/xen/common/timer.c
index 0547ea3..043250e 100644
--- a/xen/common/timer.c
+++ b/xen/common/timer.c
@@ -23,6 +23,7 @@
#include <xen/symbols.h>
#include <asm/system.h>
#include <asm/desc.h>
+#include <asm/div64.h>
#include <asm/atomic.h>

/* We program the time hardware this far behind the closest deadline. */
@@ -503,16 +504,18 @@ static void timer_softirq_action(void)

s_time_t align_timer(s_time_t firsttick, uint64_t period)
{
+ uint64_t n;
if ( !period )
return firsttick;

- return firsttick + (period - 1) - ((firsttick - 1) % period);
+ n = firsttick + (period - 1) - (firsttick - 1);
+ return do_div(n, period);
}

static void dump_timer(struct timer *t, s_time_t now)
{
printk(" ex=%8"PRId64"us timer=%p cb=%p(%p)",
- (t->expires - now) / 1000, t, t->function, t->data);
+ div64(t->expires - now, 1000), t, t->function, t->data);
print_symbol(" %s\n", (unsigned long)t->function);
}

diff --git a/xen/include/asm-ia64/linux/asm-generic/div64.h b/xen/include/asm-ia64/linux/asm-generic/div64.h
index 8f4e319..820c073 100644
--- a/xen/include/asm-ia64/linux/asm-generic/div64.h
+++ b/xen/include/asm-ia64/linux/asm-generic/div64.h
@@ -55,4 +55,10 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);

#endif /* BITS_PER_LONG */

+static inline uint64_t div64(uint64_t n, uint32_t base)
+{
+ do_div(n, base);
+ return n;
+}
+
#endif /* _ASM_GENERIC_DIV64_H */
diff --git a/xen/include/asm-x86/div64.h b/xen/include/asm-x86/div64.h
index 1ce87cd..800ef2a 100644
--- a/xen/include/asm-x86/div64.h
+++ b/xen/include/asm-x86/div64.h
@@ -46,4 +46,10 @@

#endif

+static inline uint64_t div64(uint64_t n, uint32_t base)
+{
+ do_div(n, base);
+ return n;
+}
+
#endif
--
1.7.2.5


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH RFC 04/25] Replace "/" operand with div64 [ In reply to ]
Hi, Stefano
Great work from you guys! One quick comment: Just found the below logic's change maybe wrong and probably break current things.
Original logic is A+B -(C%D), but it is changed to (A+B-C)%D, so if it is not an intended fix, it should be an issue.
Thanks!
Xiantao

>diff --git a/xen/common/timer.c b/xen/common/timer.c index 0547ea3..043250e 100644
>--- a/xen/common/timer.c
>+++ b/xen/common/timer.c
>@@ -23,6 +23,7 @@
>#include <xen/symbols.h>
>#include <asm/system.h>
>#include <asm/desc.h>
>+#include <asm/div64.h>
> #include <asm/atomic.h>
>
> /* We program the time hardware this far behind the closest deadline. */ @@ -503,16 +504,18 @@ static void timer_softirq_action(void)
>
> s_time_t align_timer(s_time_t firsttick, uint64_t period) {
>+ uint64_t n;
> if ( !period )
> return firsttick;

>- return firsttick + (period - 1) - ((firsttick - 1) % period);
>+ n = firsttick + (period - 1) - (firsttick - 1);
>+ return do_div(n, period);
> }



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH RFC 04/25] Replace "/" operand with div64 [ In reply to ]
Also, I assume the gcc arm target can at least do 64-bit arithmetic via
library calls, which you could then implement in arch/arm. __divdi3 etc.
Perhaps you intend to do this anyway and do_div() here is a bandaid.

-- Keir

On 07/12/2011 07:00, "Zhang, Xiantao" <xiantao.zhang@intel.com> wrote:

> Hi, Stefano
> Great work from you guys! One quick comment: Just found the below logic's
> change maybe wrong and probably break current things.
> Original logic is A+B -(C%D), but it is changed to (A+B-C)%D, so if it is
> not an intended fix, it should be an issue.
> Thanks!
> Xiantao
>
>> diff --git a/xen/common/timer.c b/xen/common/timer.c index 0547ea3..043250e
>> 100644
>> --- a/xen/common/timer.c
>> +++ b/xen/common/timer.c
>> @@ -23,6 +23,7 @@
>> #include <xen/symbols.h>
>> #include <asm/system.h>
>> #include <asm/desc.h>
>> +#include <asm/div64.h>
>> #include <asm/atomic.h>
>>
>> /* We program the time hardware this far behind the closest deadline. */ @@
>> -503,16 +504,18 @@ static void timer_softirq_action(void)
>>
>> s_time_t align_timer(s_time_t firsttick, uint64_t period) {
>> + uint64_t n;
>> if ( !period )
>> return firsttick;
>
>> - return firsttick + (period - 1) - ((firsttick - 1) % period);
>> + n = firsttick + (period - 1) - (firsttick - 1);
>> + return do_div(n, period);
>> }
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH RFC 04/25] Replace "/" operand with div64 [ In reply to ]
On 07/12/2011 09:12, "Keir Fraser" <keir.xen@gmail.com> wrote:

> Also, I assume the gcc arm target can at least do 64-bit arithmetic via
> library calls, which you could then implement in arch/arm. __divdi3 etc.
> Perhaps you intend to do this anyway and do_div() here is a bandaid.

Of course we already implement __divdi3/__udivdi3 in common/lib.c. That
should already have been sufficient so not sure why this timer.c change
would be needed at all?

> -- Keir
>
> On 07/12/2011 07:00, "Zhang, Xiantao" <xiantao.zhang@intel.com> wrote:
>
>> Hi, Stefano
>> Great work from you guys! One quick comment: Just found the below logic's
>> change maybe wrong and probably break current things.
>> Original logic is A+B -(C%D), but it is changed to (A+B-C)%D, so if it is
>> not an intended fix, it should be an issue.
>> Thanks!
>> Xiantao
>>
>>> diff --git a/xen/common/timer.c b/xen/common/timer.c index 0547ea3..043250e
>>> 100644
>>> --- a/xen/common/timer.c
>>> +++ b/xen/common/timer.c
>>> @@ -23,6 +23,7 @@
>>> #include <xen/symbols.h>
>>> #include <asm/system.h>
>>> #include <asm/desc.h>
>>> +#include <asm/div64.h>
>>> #include <asm/atomic.h>
>>>
>>> /* We program the time hardware this far behind the closest deadline. */ @@
>>> -503,16 +504,18 @@ static void timer_softirq_action(void)
>>>
>>> s_time_t align_timer(s_time_t firsttick, uint64_t period) {
>>> + uint64_t n;
>>> if ( !period )
>>> return firsttick;
>>
>>> - return firsttick + (period - 1) - ((firsttick - 1) % period);
>>> + n = firsttick + (period - 1) - (firsttick - 1);
>>> + return do_div(n, period);
>>> }
>>
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xensource.com
>> http://lists.xensource.com/xen-devel
>
>



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH RFC 04/25] Replace "/" operand with div64 [ In reply to ]
>>> On 06.12.11 at 19:19, <stefano.stabellini@eu.citrix.com> wrote:
> ARM does not have a division operator: division has to be implemented
> in software.
> On x86 and ia64 div64 falls back to a do_div based implementation.

But this needs to be done carefully and correctly - there's no
one-fits-all div64() implementation.

> --- a/xen/common/sched_sedf.c
> +++ b/xen/common/sched_sedf.c
> @@ -127,7 +128,7 @@ struct sedf_cpu_info {
>
> #define PERIOD_BEGIN(inf) ((inf)->deadl_abs - (inf)->period)
>
> -#define DIV_UP(x,y) (((x) + (y) - 1) / y)
> +#define DIV_UP(x,y) div64((x) + (y) - 1, y)

There are uses of this with y being s_time_t.

> #define extra_runs(inf) ((inf->status) & 6)
> #define extra_get_cur_q(inf) (((inf->status & 6) >> 1)-1)
> @@ -678,8 +679,7 @@ static void desched_extra_dom(s_time_t now, struct vcpu *d)
> utilization and is used somewhat incremental!*/
> if ( !inf->extraweight )
> /*NB: use fixed point arithmetic with 10 bits*/
> - inf->score[EXTRA_UTIL_Q] = (inf->period << 10) /
> - inf->slice;
> + inf->score[EXTRA_UTIL_Q] = div64(inf->period << 10, inf->slice);

inf->slice is s_time_t, i.e. 64-bit (and signed, but that's not relevant here).

> else
> /*conversion between realtime utilisation and extrawieght:
> full (ie 100%) utilization is equivalent to 128 extraweight*/
> @@ -996,8 +996,8 @@ static void unblock_short_extra_support(
>
> if ( inf->short_block_lost_tot )
> {
> - inf->score[0] = (inf->period << 10) /
> - inf->short_block_lost_tot;
> + inf->score[0] = div64(inf->period << 10,
> + inf->short_block_lost_tot);

inf->short_block_lost_tot is s_time_t, too.

> #ifdef SEDF_STATS
> inf->pen_extra_blocks++;
> #endif
> @@ -1224,8 +1224,8 @@ static void sedf_dump_domain(struct vcpu *d)
>
> #ifdef SEDF_STATS
> if ( EDOM_INFO(d)->block_time_tot != 0 )
> - printk(" pen=%"PRIu64"%%", (EDOM_INFO(d)->penalty_time_tot * 100) /
> - EDOM_INFO(d)->block_time_tot);
> + printk(" pen=%"PRIu64"%%",
> + div64(EDOM_INFO(d)->penalty_time_tot * 100, EDOM_INFO(d)->block_time_tot));

As is ->block_time_tot.

> if ( EDOM_INFO(d)->block_tot != 0 )
> printk("\n blks=%u sh=%u (%u%%) (shc=%u (%u%%) shex=%i "\
> "shexsl=%i) l=%u (%u%%) avg: b=%"PRIu64" p=%"PRIu64"",
> @@ -1357,9 +1357,9 @@ static int sedf_adjust_weights(struct cpupool *c,
> struct xen_domctl_scheduler_op
> /*check for overflows*/
> ASSERT((WEIGHT_PERIOD < ULONG_MAX)
> && (EDOM_INFO(p)->slice_orig < ULONG_MAX));
> - sumt[cpu] +=
> - (WEIGHT_PERIOD * EDOM_INFO(p)->slice_orig) /
> - EDOM_INFO(p)->period_orig;
> + sumt[cpu] += div64(
> + WEIGHT_PERIOD * EDOM_INFO(p)->slice_orig,
> + EDOM_INFO(p)->period_orig);

And ->period_orig.

> }
> }
> }
> --- a/xen/common/timer.c
> +++ b/xen/common/timer.c
> @@ -503,16 +504,18 @@ static void timer_softirq_action(void)
>
> s_time_t align_timer(s_time_t firsttick, uint64_t period)
> {
> + uint64_t n;

uint64_t n = firsttick - 1;

> if ( !period )
> return firsttick;
>
> - return firsttick + (period - 1) - ((firsttick - 1) % period);
> + n = firsttick + (period - 1) - (firsttick - 1);
> + return do_div(n, period);

return firsttick + (period - 1) - do_div(n, period);

But again period is a 64-bit value, so using do_div() isn't correct
here.

> }
>
> static void dump_timer(struct timer *t, s_time_t now)
> --- a/xen/include/asm-ia64/linux/asm-generic/div64.h
> +++ b/xen/include/asm-ia64/linux/asm-generic/div64.h
> @@ -55,4 +55,10 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t
> divisor);
>
> #endif /* BITS_PER_LONG */
>
> +static inline uint64_t div64(uint64_t n, uint32_t base)

Return value type ought to be uint32_t for this particular flavor. More
flavors (64-bit divisor, signed divisor) may/will be needed.

> +{
> + do_div(n, base);
> + return n;
> +}
> +
> #endif /* _ASM_GENERIC_DIV64_H */
> --- a/xen/include/asm-x86/div64.h
> +++ b/xen/include/asm-x86/div64.h
> @@ -46,4 +46,10 @@
>
> #endif
>
> +static inline uint64_t div64(uint64_t n, uint32_t base)

Same here.

> +{
> + do_div(n, base);
> + return n;
> +}
> +
> #endif

Did you really test this in its current shape on x86 (32-bit and 64-bit)?

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH RFC 04/25] Replace "/" operand with div64 [ In reply to ]
On 07/12/2011 09:24, "Jan Beulich" <JBeulich@suse.com> wrote:

>>>> On 06.12.11 at 19:19, <stefano.stabellini@eu.citrix.com> wrote:
>> ARM does not have a division operator: division has to be implemented
>> in software.
>> On x86 and ia64 div64 falls back to a do_div based implementation.
>
> But this needs to be done carefully and correctly - there's no
> one-fits-all div64() implementation.

I'm sure gcc-arm must emit lib calls for divisions. Maybe arch/arm needs to
implement some of those if arm doesn't support even 32-bit divide. Common
lib code covers only 64-bit divide.

-- Keir



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH RFC 04/25] Replace "/" operand with div64 [ In reply to ]
On Wed, 7 Dec 2011, Zhang, Xiantao wrote:
> Hi, Stefano
> Great work from you guys! One quick comment: Just found the below logic's change maybe wrong and probably break current things.
> Original logic is A+B -(C%D), but it is changed to (A+B-C)%D, so if it is not an intended fix, it should be an issue.
> Thanks!
> Xiantao

True! Thanks for spotting this!

> >diff --git a/xen/common/timer.c b/xen/common/timer.c index 0547ea3..043250e 100644
> >--- a/xen/common/timer.c
> >+++ b/xen/common/timer.c
> >@@ -23,6 +23,7 @@
> >#include <xen/symbols.h>
> >#include <asm/system.h>
> >#include <asm/desc.h>
> >+#include <asm/div64.h>
> > #include <asm/atomic.h>
> >
> > /* We program the time hardware this far behind the closest deadline. */ @@ -503,16 +504,18 @@ static void timer_softirq_action(void)
> >
> > s_time_t align_timer(s_time_t firsttick, uint64_t period) {
> >+ uint64_t n;
> > if ( !period )
> > return firsttick;
>
> >- return firsttick + (period - 1) - ((firsttick - 1) % period);
> >+ n = firsttick + (period - 1) - (firsttick - 1);
> >+ return do_div(n, period);
> > }
>
>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH RFC 04/25] Replace "/" operand with div64 [ In reply to ]
On 07/12/2011 12:23, "Stefano Stabellini" <stefano.stabellini@eu.citrix.com>
wrote:

> On Wed, 7 Dec 2011, Zhang, Xiantao wrote:
>> Hi, Stefano
>> Great work from you guys! One quick comment: Just found the below logic's
>> change maybe wrong and probably break current things.
>> Original logic is A+B -(C%D), but it is changed to (A+B-C)%D, so if it is
>> not an intended fix, it should be an issue.
>> Thanks!
>> Xiantao
>
> True! Thanks for spotting this!

For the avoidance of doubt: this patch 04/25 is wrongheaded, and I will nack
it if it appears in the final patch series. You probably got this impression
from me already. ;-)

>>> diff --git a/xen/common/timer.c b/xen/common/timer.c index 0547ea3..043250e
>>> 100644
>>> --- a/xen/common/timer.c
>>> +++ b/xen/common/timer.c
>>> @@ -23,6 +23,7 @@
>>> #include <xen/symbols.h>
>>> #include <asm/system.h>
>>> #include <asm/desc.h>
>>> +#include <asm/div64.h>
>>> #include <asm/atomic.h>
>>>
>>> /* We program the time hardware this far behind the closest deadline. */ @@
>>> -503,16 +504,18 @@ static void timer_softirq_action(void)
>>>
>>> s_time_t align_timer(s_time_t firsttick, uint64_t period) {
>>> + uint64_t n;
>>> if ( !period )
>>> return firsttick;
>>
>>> - return firsttick + (period - 1) - ((firsttick - 1) % period);
>>> + n = firsttick + (period - 1) - (firsttick - 1);
>>> + return do_div(n, period);
>>> }
>>
>>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Re: [PATCH RFC 04/25] Replace "/" operand with div64 [ In reply to ]
On Wed, 7 Dec 2011, Keir Fraser wrote:
> On 07/12/2011 12:23, "Stefano Stabellini" <stefano.stabellini@eu.citrix.com>
> wrote:
>
> > On Wed, 7 Dec 2011, Zhang, Xiantao wrote:
> >> Hi, Stefano
> >> Great work from you guys! One quick comment: Just found the below logic's
> >> change maybe wrong and probably break current things.
> >> Original logic is A+B -(C%D), but it is changed to (A+B-C)%D, so if it is
> >> not an intended fix, it should be an issue.
> >> Thanks!
> >> Xiantao
> >
> > True! Thanks for spotting this!
>
> For the avoidance of doubt: this patch 04/25 is wrongheaded, and I will nack
> it if it appears in the final patch series. You probably got this impression
> from me already. ;-)

Yes, I got it :)
I think that the right thing to do is removing this patch and
implementing __aeabi_ldivmod and __aeabi_uldivmod in assembly for ARM,
that would give gcc everything it needs to compile "/".
I have got a simple implementation based on __qdivrem and seems to work
OK.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel