20
20
#include "tick-internal.h"
21
21
#include "timekeeping_internal.h"
22
22
23
+ static noinline u64 cycles_to_nsec_safe (struct clocksource * cs , u64 start , u64 end )
24
+ {
25
+ u64 delta = clocksource_delta (end , start , cs -> mask );
26
+
27
+ if (likely (delta < cs -> max_cycles ))
28
+ return clocksource_cyc2ns (delta , cs -> mult , cs -> shift );
29
+
30
+ return mul_u64_u32_shr (delta , cs -> mult , cs -> shift );
31
+ }
32
+
23
33
/**
24
34
* clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks
25
35
* @mult: pointer to mult variable
@@ -222,8 +232,8 @@ enum wd_read_status {
222
232
static enum wd_read_status cs_watchdog_read (struct clocksource * cs , u64 * csnow , u64 * wdnow )
223
233
{
224
234
unsigned int nretries , max_retries ;
225
- u64 wd_end , wd_end2 , wd_delta ;
226
235
int64_t wd_delay , wd_seq_delay ;
236
+ u64 wd_end , wd_end2 ;
227
237
228
238
max_retries = clocksource_get_max_watchdog_retry ();
229
239
for (nretries = 0 ; nretries <= max_retries ; nretries ++ ) {
@@ -234,9 +244,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow,
234
244
wd_end2 = watchdog -> read (watchdog );
235
245
local_irq_enable ();
236
246
237
- wd_delta = clocksource_delta (wd_end , * wdnow , watchdog -> mask );
238
- wd_delay = clocksource_cyc2ns (wd_delta , watchdog -> mult ,
239
- watchdog -> shift );
247
+ wd_delay = cycles_to_nsec_safe (watchdog , * wdnow , wd_end );
240
248
if (wd_delay <= WATCHDOG_MAX_SKEW ) {
241
249
if (nretries > 1 || nretries >= max_retries ) {
242
250
pr_warn ("timekeeping watchdog on CPU%d: %s retried %d times before success\n" ,
@@ -254,8 +262,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow,
254
262
* report system busy, reinit the watchdog and skip the current
255
263
* watchdog test.
256
264
*/
257
- wd_delta = clocksource_delta (wd_end2 , wd_end , watchdog -> mask );
258
- wd_seq_delay = clocksource_cyc2ns (wd_delta , watchdog -> mult , watchdog -> shift );
265
+ wd_seq_delay = cycles_to_nsec_safe (watchdog , wd_end , wd_end2 );
259
266
if (wd_seq_delay > WATCHDOG_MAX_SKEW /2 )
260
267
goto skip_test ;
261
268
}
@@ -366,8 +373,7 @@ void clocksource_verify_percpu(struct clocksource *cs)
366
373
delta = (csnow_end - csnow_mid ) & cs -> mask ;
367
374
if (delta < 0 )
368
375
cpumask_set_cpu (cpu , & cpus_ahead );
369
- delta = clocksource_delta (csnow_end , csnow_begin , cs -> mask );
370
- cs_nsec = clocksource_cyc2ns (delta , cs -> mult , cs -> shift );
376
+ cs_nsec = cycles_to_nsec_safe (cs , csnow_begin , csnow_end );
371
377
if (cs_nsec > cs_nsec_max )
372
378
cs_nsec_max = cs_nsec ;
373
379
if (cs_nsec < cs_nsec_min )
@@ -398,8 +404,8 @@ static inline void clocksource_reset_watchdog(void)
398
404
399
405
static void clocksource_watchdog (struct timer_list * unused )
400
406
{
401
- u64 csnow , wdnow , cslast , wdlast , delta ;
402
407
int64_t wd_nsec , cs_nsec , interval ;
408
+ u64 csnow , wdnow , cslast , wdlast ;
403
409
int next_cpu , reset_pending ;
404
410
struct clocksource * cs ;
405
411
enum wd_read_status read_ret ;
@@ -456,12 +462,8 @@ static void clocksource_watchdog(struct timer_list *unused)
456
462
continue ;
457
463
}
458
464
459
- delta = clocksource_delta (wdnow , cs -> wd_last , watchdog -> mask );
460
- wd_nsec = clocksource_cyc2ns (delta , watchdog -> mult ,
461
- watchdog -> shift );
462
-
463
- delta = clocksource_delta (csnow , cs -> cs_last , cs -> mask );
464
- cs_nsec = clocksource_cyc2ns (delta , cs -> mult , cs -> shift );
465
+ wd_nsec = cycles_to_nsec_safe (watchdog , cs -> wd_last , wdnow );
466
+ cs_nsec = cycles_to_nsec_safe (cs , cs -> cs_last , csnow );
465
467
wdlast = cs -> wd_last ; /* save these in case we print them */
466
468
cslast = cs -> cs_last ;
467
469
cs -> cs_last = csnow ;
@@ -832,7 +834,7 @@ void clocksource_start_suspend_timing(struct clocksource *cs, u64 start_cycles)
832
834
*/
833
835
u64 clocksource_stop_suspend_timing (struct clocksource * cs , u64 cycle_now )
834
836
{
835
- u64 now , delta , nsec = 0 ;
837
+ u64 now , nsec = 0 ;
836
838
837
839
if (!suspend_clocksource )
838
840
return 0 ;
@@ -847,12 +849,8 @@ u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now)
847
849
else
848
850
now = suspend_clocksource -> read (suspend_clocksource );
849
851
850
- if (now > suspend_start ) {
851
- delta = clocksource_delta (now , suspend_start ,
852
- suspend_clocksource -> mask );
853
- nsec = mul_u64_u32_shr (delta , suspend_clocksource -> mult ,
854
- suspend_clocksource -> shift );
855
- }
852
+ if (now > suspend_start )
853
+ nsec = cycles_to_nsec_safe (suspend_clocksource , suspend_start , now );
856
854
857
855
/*
858
856
* Disable the suspend timer to save power if current clocksource is
0 commit comments