@@ -33,29 +33,64 @@ struct ce_unbind {
33
33
int res ;
34
34
};
35
35
36
- /**
37
- * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds
38
- * @latch: value to convert
39
- * @evt: pointer to clock event device descriptor
40
- *
41
- * Math helper, returns latch value converted to nanoseconds (bound checked)
42
- */
43
- u64 clockevent_delta2ns (unsigned long latch , struct clock_event_device * evt )
36
+ static u64 cev_delta2ns (unsigned long latch , struct clock_event_device * evt ,
37
+ bool ismax )
44
38
{
45
39
u64 clc = (u64 ) latch << evt -> shift ;
40
+ u64 rnd ;
46
41
47
42
if (unlikely (!evt -> mult )) {
48
43
evt -> mult = 1 ;
49
44
WARN_ON (1 );
50
45
}
46
+ rnd = (u64 ) evt -> mult - 1 ;
47
+
48
+ /*
49
+ * Upper bound sanity check. If the backwards conversion is
50
+ * not equal latch, we know that the above shift overflowed.
51
+ */
52
+ if ((clc >> evt -> shift ) != (u64 )latch )
53
+ clc = ~0ULL ;
54
+
55
+ /*
56
+ * Scaled math oddities:
57
+ *
58
+ * For mult <= (1 << shift) we can safely add mult - 1 to
59
+ * prevent integer rounding loss. So the backwards conversion
60
+ * from nsec to device ticks will be correct.
61
+ *
62
+ * For mult > (1 << shift), i.e. device frequency is > 1GHz we
63
+ * need to be careful. Adding mult - 1 will result in a value
64
+ * which when converted back to device ticks can be larger
65
+ * than latch by up to (mult - 1) >> shift. For the min_delta
66
+ * calculation we still want to apply this in order to stay
67
+ * above the minimum device ticks limit. For the upper limit
68
+ * we would end up with a latch value larger than the upper
69
+ * limit of the device, so we omit the add to stay below the
70
+ * device upper boundary.
71
+ *
72
+ * Also omit the add if it would overflow the u64 boundary.
73
+ */
74
+ if ((~0ULL - clc > rnd ) &&
75
+ (!ismax || evt -> mult <= (1U << evt -> shift )))
76
+ clc += rnd ;
51
77
52
78
do_div (clc , evt -> mult );
53
- if (clc < 1000 )
54
- clc = 1000 ;
55
- if (clc > KTIME_MAX )
56
- clc = KTIME_MAX ;
57
79
58
- return clc ;
80
+ /* Deltas less than 1usec are pointless noise */
81
+ return clc > 1000 ? clc : 1000 ;
82
+ }
83
+
84
+ /**
85
+ * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds
86
+ * @latch: value to convert
87
+ * @evt: pointer to clock event device descriptor
88
+ *
89
+ * Math helper, returns latch value converted to nanoseconds (bound checked)
90
+ */
91
+ u64 clockevent_delta2ns (unsigned long latch , struct clock_event_device * evt )
92
+ {
93
+ return cev_delta2ns (latch , evt , false);
59
94
}
60
95
EXPORT_SYMBOL_GPL (clockevent_delta2ns );
61
96
@@ -380,8 +415,8 @@ void clockevents_config(struct clock_event_device *dev, u32 freq)
380
415
sec = 600 ;
381
416
382
417
clockevents_calc_mult_shift (dev , freq , sec );
383
- dev -> min_delta_ns = clockevent_delta2ns (dev -> min_delta_ticks , dev );
384
- dev -> max_delta_ns = clockevent_delta2ns (dev -> max_delta_ticks , dev );
418
+ dev -> min_delta_ns = cev_delta2ns (dev -> min_delta_ticks , dev , false );
419
+ dev -> max_delta_ns = cev_delta2ns (dev -> max_delta_ticks , dev , true );
385
420
}
386
421
387
422
/**
0 commit comments