From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> To: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>, Thomas Gleixner <tglx@linutronix.de>, Linux-Renesas <linux-renesas-soc@vger.kernel.org>, Vladimir Barinov <vladimir.barinov@cogentembedded.com>, andrey.gusakov@cogentembedded.com, Mikhail Ulyanov <mikhail.ulyanov@cogentembedded.com>, Linux-sh list <linux-sh@vger.kernel.org> Subject: Re: [PATCH v2] clocksource: sh_cmt: fixup for 64-bit machines Date: Sat, 08 Sep 2018 17:20:42 +0000 [thread overview] Message-ID: <8ffc1f31-607a-2550-59bb-bba1da4e1f78@cogentembedded.com> (raw) In-Reply-To: <CAMuHMdW0KkVYyMeo3wwnyGzn1tAA5Tkrq_cKVjHCFnYc9tALjw@mail.gmail.com> Hello! On 09/06/2018 03:18 PM, Geert Uytterhoeven wrote: >> When trying to use CMT for clockevents on R-Car gen3 SoCs, I noticed >> that 'max_delta_ns' for the broadcast timer (CMT) was shown as 1000 in >> /proc/timer_list. It turned out that when calculating it, the driver did >> 1 << 32 (causing what I think was undefined behavior) resulting in a zero >> delta, later clamped to 1000 by cev_delta2ns(). The root cause turned out >> to be that the driver abused *unsigned long* for the CMT register values >> (which are 16/32-bit), so that the calculation of 'ch->max_match_value' >> in sh_cmt_setup_channel() used the worng branch. Using more proper 'u32' >> instead fixed 'max_delta_ns' and even fixed the switching an active >> clocksource to CMT (which caused the system to turn non-interactive >> before). >> >> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> >> >> --- >> This patch is against the 'tip.git' repo's 'timers/core' branch. >> The CMT driver wasn't ever used on SH64; on R-Car gen3 (ARM64) I'm only >> enabling building of this driver now, so not sure how urgent is this... >> >> Changes in version 2: >> - completely redid the patch, fixing abuse of *unsigned long* for the CMT >> register values. > > Thanks for the update! > >> --- tip.orig/drivers/clocksource/sh_cmt.c >> +++ tip/drivers/clocksource/sh_cmt.c >> @@ -82,14 +82,13 @@ struct sh_cmt_info { >> unsigned long clear_bits; > > "clear_bits" should be u32, as it corresponds to a register value. OK. >> @@ -103,9 +102,9 @@ struct sh_cmt_channel { >> >> unsigned int timer_bit; >> unsigned long flags; > > While no register value, "flags" can be unsigned int, too. OK to leave that for another patch? >> - unsigned long match_value; >> - unsigned long next_match_value; >> - unsigned long max_match_value; >> + u32 match_value; >> + u32 next_match_value; >> + u32 max_match_value; >> raw_spinlock_t lock; >> struct clock_event_device ced; >> struct clocksource cs; > >> @@ -290,7 +284,7 @@ static inline void sh_cmt_write_cmcor(st >> static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch, > > Return type should be "u32". Thanks, missed it... >> int *has_wrapped) > > While not "unsigned long", "has_wrapped" is used to store a register value, > so I think it should be changed to "u32 *". Hm, indeed... >> { >> - unsigned long v1, v2, v3; >> + u32 v1, v2, v3; >> int o1, o2; > > While not "unsigned long", "o1" and "o2" contain register values, so I think > they should be "u32". OK, lemme try that... >> o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit; > > "overflow_bit" should become "u32", too. I've figured. :-) > >> @@ -619,9 +614,10 @@ static struct sh_cmt_channel *cs_to_sh_c >> static u64 sh_cmt_clocksource_read(struct clocksource *cs) >> { >> struct sh_cmt_channel *ch = cs_to_sh_cmt(cs); >> - unsigned long flags, raw; >> + unsigned long flags; >> unsigned long value; >> int has_wrapped; >> + u32 raw; >> >> raw_spin_lock_irqsave(&ch->lock, flags); >> value = ch->total_cycles; > > "value" and "total_cycles" should be "u64". But that's a separate bug fix. And for 32-bit CPUs, I guess? Will look into it... > Not in the context, so I cannot comment to it, but "sh_cmt_info.width" should > be "unsigned int", too. Separate patch? > Gr{oetje,eeting}s, > > Geert MBR, Sergei
WARNING: multiple messages have this Message-ID (diff)
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> To: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>, Thomas Gleixner <tglx@linutronix.de>, Linux-Renesas <linux-renesas-soc@vger.kernel.org>, Vladimir Barinov <vladimir.barinov@cogentembedded.com>, andrey.gusakov@cogentembedded.com, Mikhail Ulyanov <mikhail.ulyanov@cogentembedded.com>, Linux-sh list <linux-sh@vger.kernel.org> Subject: Re: [PATCH v2] clocksource: sh_cmt: fixup for 64-bit machines Date: Sat, 8 Sep 2018 20:20:42 +0300 [thread overview] Message-ID: <8ffc1f31-607a-2550-59bb-bba1da4e1f78@cogentembedded.com> (raw) In-Reply-To: <CAMuHMdW0KkVYyMeo3wwnyGzn1tAA5Tkrq_cKVjHCFnYc9tALjw@mail.gmail.com> Hello! On 09/06/2018 03:18 PM, Geert Uytterhoeven wrote: >> When trying to use CMT for clockevents on R-Car gen3 SoCs, I noticed >> that 'max_delta_ns' for the broadcast timer (CMT) was shown as 1000 in >> /proc/timer_list. It turned out that when calculating it, the driver did >> 1 << 32 (causing what I think was undefined behavior) resulting in a zero >> delta, later clamped to 1000 by cev_delta2ns(). The root cause turned out >> to be that the driver abused *unsigned long* for the CMT register values >> (which are 16/32-bit), so that the calculation of 'ch->max_match_value' >> in sh_cmt_setup_channel() used the worng branch. Using more proper 'u32' >> instead fixed 'max_delta_ns' and even fixed the switching an active >> clocksource to CMT (which caused the system to turn non-interactive >> before). >> >> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> >> >> --- >> This patch is against the 'tip.git' repo's 'timers/core' branch. >> The CMT driver wasn't ever used on SH64; on R-Car gen3 (ARM64) I'm only >> enabling building of this driver now, so not sure how urgent is this... >> >> Changes in version 2: >> - completely redid the patch, fixing abuse of *unsigned long* for the CMT >> register values. > > Thanks for the update! > >> --- tip.orig/drivers/clocksource/sh_cmt.c >> +++ tip/drivers/clocksource/sh_cmt.c >> @@ -82,14 +82,13 @@ struct sh_cmt_info { >> unsigned long clear_bits; > > "clear_bits" should be u32, as it corresponds to a register value. OK. >> @@ -103,9 +102,9 @@ struct sh_cmt_channel { >> >> unsigned int timer_bit; >> unsigned long flags; > > While no register value, "flags" can be unsigned int, too. OK to leave that for another patch? >> - unsigned long match_value; >> - unsigned long next_match_value; >> - unsigned long max_match_value; >> + u32 match_value; >> + u32 next_match_value; >> + u32 max_match_value; >> raw_spinlock_t lock; >> struct clock_event_device ced; >> struct clocksource cs; > >> @@ -290,7 +284,7 @@ static inline void sh_cmt_write_cmcor(st >> static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch, > > Return type should be "u32". Thanks, missed it... >> int *has_wrapped) > > While not "unsigned long", "has_wrapped" is used to store a register value, > so I think it should be changed to "u32 *". Hm, indeed... >> { >> - unsigned long v1, v2, v3; >> + u32 v1, v2, v3; >> int o1, o2; > > While not "unsigned long", "o1" and "o2" contain register values, so I think > they should be "u32". OK, lemme try that... >> o1 = sh_cmt_read_cmcsr(ch) & ch->cmt->info->overflow_bit; > > "overflow_bit" should become "u32", too. I've figured. :-) > >> @@ -619,9 +614,10 @@ static struct sh_cmt_channel *cs_to_sh_c >> static u64 sh_cmt_clocksource_read(struct clocksource *cs) >> { >> struct sh_cmt_channel *ch = cs_to_sh_cmt(cs); >> - unsigned long flags, raw; >> + unsigned long flags; >> unsigned long value; >> int has_wrapped; >> + u32 raw; >> >> raw_spin_lock_irqsave(&ch->lock, flags); >> value = ch->total_cycles; > > "value" and "total_cycles" should be "u64". But that's a separate bug fix. And for 32-bit CPUs, I guess? Will look into it... > Not in the context, so I cannot comment to it, but "sh_cmt_info.width" should > be "unsigned int", too. Separate patch? > Gr{oetje,eeting}s, > > Geert MBR, Sergei
next prev parent reply other threads:[~2018-09-08 17:20 UTC|newest] Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-09-04 18:31 [PATCH v2] clocksource: sh_cmt: fixup for 64-bit machines Sergei Shtylyov 2018-09-04 18:31 ` Sergei Shtylyov 2018-09-06 12:18 ` Geert Uytterhoeven 2018-09-06 12:18 ` Geert Uytterhoeven 2018-09-08 17:20 ` Sergei Shtylyov [this message] 2018-09-08 17:20 ` Sergei Shtylyov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=8ffc1f31-607a-2550-59bb-bba1da4e1f78@cogentembedded.com \ --to=sergei.shtylyov@cogentembedded.com \ --cc=andrey.gusakov@cogentembedded.com \ --cc=daniel.lezcano@linaro.org \ --cc=geert@linux-m68k.org \ --cc=linux-renesas-soc@vger.kernel.org \ --cc=linux-sh@vger.kernel.org \ --cc=mikhail.ulyanov@cogentembedded.com \ --cc=tglx@linutronix.de \ --cc=vladimir.barinov@cogentembedded.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.