Thread (6 messages) 6 messages, 3 authors, 2016-06-30

Re: [PATCH v3] cpuidle: Fix last_residency division

flat view

From: Nicolas Pitre <hidden>
Date: 2016-06-29 15:01:58
Also in: linux-pm

On Wed, 29 Jun 2016, Daniel Lezcano wrote:
On 06/29/2016 09:06 AM, Shreyas B. Prabhu wrote:
quoted
diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h
index f87f399..c8ea5ad 100644
--- a/drivers/cpuidle/cpuidle.h
+++ b/drivers/cpuidle/cpuidle.h
@@ -68,4 +68,27 @@ static inline void
cpuidle_coupled_unregister_device(struct cpuidle_device *dev)
  }
  #endif

+/*
+ * Used for calculating last_residency in usec. Optimized for case
+ * where last_residency in nsecs is < INT_MAX/2 by using faster
+ * approximation. Approximated value has less than 1% error.
+ */
+static inline int convert_nsec_to_usec(u64 nsec)
+{
+	if (likely(nsec < INT_MAX / 2)) {
UINT_MAX ?
Actually this can be better than that.
quoted
+		int usec = (int)nsec;
First, you'll want an unsigned type. Given the provided argument is u64, 
we can assume there won't be any negative values here.

Then it would be wise to use a type with an explicit width, like U32.
quoted
+		usec += usec >> 5;
+		usec = usec >> 10;
+		return usec;
And now you want to maximize the available range. So not to overflow the 
first addition, we must respect:

	usec + (usec >> 5) <= 0xffffffff 
	usec + usec/32 <= 0xffffffff
	usec <= (0xffffffff * 32) / 33

Therefore:

	nsec <= 0xf83e0f82

This is much better than INT_MAX/2.
quoted
+	} else {
+		u64 usec = div_u64(nsec, 1000);
+
+		if (usec > INT_MAX)
+			usec = INT_MAX;
+		return (int)usec;
+	}
+}


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help