Skip to contentSkip to conversation

ia64: VIRT_CPU_ACCOUNTING (accurate cpu time accounting)

PATCH In review Hidetoshi Seto 2 participants 4 messages Oct 16, 2007 – Oct 30, 2007

lore
Share & tools
lore
#0 lore raw

PATCH 3/9 ia64: VIRT_CPU_ACCOUNTING (accurate cpu time accounting)

Quoted 1 line

[3/9] ia64_cputime_to_nsec.patch

We need to define the type of cputime_t.
It is clear that the unit should be better than msec. IBM arches defined it as usec.

On ia64, since the value of ar.itc is source of sched_clock(), there are enough parameters to convert cycles to nsecs.

Then, how long time we can save in u64?

 0x 1 0000 0000 0000 0000 in hex
 18446744073 709 551 616 in decimal
 if in nsec, it will overflow after 213503 days, 584 years. if in usec, x1000 above.

It seems enough even in nsec.

So I practically make it in nsec.
If there is situation which this definition is not acceptable, it would be better to have an option to switch the unit between nsec and usec.

Thanks,
H.Seto

---
 arch/ia64/ia32/elfcore32.h |    5 +++
 include/asm-ia64/cputime.h |   64 +++++++++++++++++++++++++++++----------------
 2 files changed, 47 insertions(+), 22 deletions(-)

Index: linux-2.6.23/include/asm-ia64/cputime.h =================================--- linux-2.6.23.orig/include/asm-ia64/cputime.h +++ linux-2.6.23/include/asm-ia64/cputime.h
@@ -7,6 +7,10 @@
#ifndef __IA64_CPUTIME_H
#define __IA64_CPUTIME_H

+/*
+ * If we have CONFIG_VIRT_CPU_ACCOUNTING, we measure cpu time in nsec.
+ * Otherwise we measure cpu time in jiffies using the generic definitions.
+ */
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
#include <asm-generic/cputime.h>
#else
@@ -36,47 +40,63 @@
#define cputime_to_cputime64(__ct) (__ct)

/*
- * Convert cputime <-> jiffies
+ * Convert cputime <-> jiffies (HZ)
*/
-#define cputime_to_jiffies(__ct) (__ct)
-#define jiffies_to_cputime(__jif) (__jif)
-#define cputime64_to_jiffies64(__ct) (__ct)
-#define jiffies64_to_cputime64(__jif) (__jif)
+#define cputime_to_jiffies(__ct) ((__ct) * HZ / NSEC_PER_SEC)
+#define jiffies_to_cputime(__jif) ((__jif) * NSEC_PER_SEC / HZ)
+#define cputime64_to_jiffies64(__ct) ((__ct) * HZ / NSEC_PER_SEC)
+#define jiffies64_to_cputime64(__jif) ((__jif) * NSEC_PER_SEC / HZ)

/*
* Convert cputime <-> milliseconds
*/
-#define cputime_to_msecs(__ct) jiffies_to_msecs(__ct)
-#define msecs_to_cputime(__msecs) msecs_to_jiffies(__msecs)
+#define cputime_to_msecs(__ct) ((__ct) / NSEC_PER_MSEC)
+#define msecs_to_cputime(__msecs) ((__msecs) * NSEC_PER_MSEC)

/*
* Convert cputime <-> seconds
*/
-#define cputime_to_secs(__ct) ((__ct) / HZ)
-#define secs_to_cputime(__secs) ((__secs) * HZ)
-
-/*
- * Convert cputime <-> timespec
- */
-#define timespec_to_cputime(__val) timespec_to_jiffies(__val)
-#define cputime_to_timespec(__ct,__val) jiffies_to_timespec(__ct,__val)
+#define cputime_to_secs(__ct) ((__ct) / NSEC_PER_SEC)
+#define secs_to_cputime(__secs) ((__secs) * NSEC_PER_SEC)

/*
- * Convert cputime <-> timeval
+ * Convert cputime <-> timespec (nsec)
*/
-#define timeval_to_cputime(__val) timeval_to_jiffies(__val)
-#define cputime_to_timeval(__ct,__val) jiffies_to_timeval(__ct,__val)
+static inline cputime_t timespec_to_cputime(struct timespec *val) +{
+ cputime_t ret = val->tv_sec * NSEC_PER_SEC;
+ return (ret + val->tv_nsec);
+}
+static inline void cputime_to_timespec(const cputime_t ct, struct timespec *val) +{
+ val->tv_sec = ct / NSEC_PER_SEC;
+ val->tv_nsec = ct % NSEC_PER_SEC;
+}
+
+/*
+ * Convert cputime <-> timeval (msec)
+ */
+static inline cputime_t timeval_to_cputime(struct timeval *val)
+{
+ cputime_t ret = val->tv_sec * NSEC_PER_SEC;
+ return (ret + val->tv_usec * NSEC_PER_USEC);
+}
+static inline void cputime_to_timeval(const cputime_t ct, struct timeval *val) +{
+ val->tv_sec = ct / NSEC_PER_SEC;
+ val->tv_usec = (ct % NSEC_PER_SEC) / NSEC_PER_USEC;
+}

/*
- * Convert cputime <-> clock
+ * Convert cputime <-> clock (USER_HZ)
*/
-#define cputime_to_clock_t(__ct) jiffies_to_clock_t(__ct)
-#define clock_t_to_cputime(__x) clock_t_to_jiffies(__x)
+#define cputime_to_clock_t(__ct) ((__ct) * USER_HZ / NSEC_PER_SEC)
+#define clock_t_to_cputime(__x) ((__x) * NSEC_PER_SEC / USER_HZ)

/*
* Convert cputime64 to clock.
*/
-#define cputime64_to_clock_t(__ct) jiffies_64_to_clock_t(__ct)
+#define cputime64_to_clock_t(__ct) cputime_to_clock_t((cputime_t)__ct)

#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
#endif /* __IA64_CPUTIME_H */
Index: linux-2.6.23/arch/ia64/ia32/elfcore32.h =================================--- linux-2.6.23.orig/arch/ia64/ia32/elfcore32.h +++ linux-2.6.23/arch/ia64/ia32/elfcore32.h
@@ -30,7 +30,12 @@
int si_errno; /* errno */
};

+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+#define cputime_to_timeval(a,b) \
+ do { (b)->tv_usec = 0; (b)->tv_sec = (a)/NSEC_PER_SEC; } while(0)
+#else
#define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
+#endif

struct elf_prstatus
{

#1 lore raw
Quoted 52 lines · Hidetoshi Seto
Quoted 1 line

[3/9] ia64_cputime_to_nsec.patch

We need to define the type of cputime_t.
It is clear that the unit should be better than msec. IBM arches defined it as usec.

On ia64, since the value of ar.itc is source of sched_clock(), there are enough parameters to convert cycles to nsecs.

Then, how long time we can save in u64?

 0x 1 0000 0000 0000 0000 in hex
 18446744073 709 551 616 in decimal
 if in nsec, it will overflow after 213503 days, 584 years. if in usec, x1000 above.

It seems enough even in nsec.

So I practically make it in nsec.
If there is situation which this definition is not acceptable, it would be better to have an option to switch the unit between nsec and usec.

Thanks,
H.Seto

---
 arch/ia64/ia32/elfcore32.h |    5 +++
 include/asm-ia64/cputime.h |   64 +++++++++++++++++++++++++++++----------------
 2 files changed, 47 insertions(+), 22 deletions(-)

Index: linux-2.6.23/include/asm-ia64/cputime.h =================================> --- linux-2.6.23.orig/include/asm-ia64/cputime.h +++ linux-2.6.23/include/asm-ia64/cputime.h

(quoted diff) +4 -1
@@ -7,6 +7,10 @@
 #ifndef __IA64_CPUTIME_H
 #define __IA64_CPUTIME_H
 
+/*
+ * If we have CONFIG_VIRT_CPU_ACCOUNTING, we measure cpu time in nsec.
+ * Otherwise we measure cpu time in jiffies using the generic definitions.
+ */
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 #include <asm-generic/cputime.h>
 #else
@@ -36,47 +40,63 @@
 #define cputime_to_cputime64(__ct)	(__ct)
 
 /*
- * Convert cputime <-> jiffies

Review line 48

Quoted 10 lines
(quoted diff) +5 -4
+ * Convert cputime <-> jiffies (HZ)
  */
-#define cputime_to_jiffies(__ct)	(__ct)
-#define jiffies_to_cputime(__jif)	(__jif)
-#define cputime64_to_jiffies64(__ct)	(__ct)
-#define jiffies64_to_cputime64(__jif)	(__jif)
+#define cputime_to_jiffies(__ct)	((__ct) * HZ / NSEC_PER_SEC)
+#define jiffies_to_cputime(__jif)	((__jif) * NSEC_PER_SEC / HZ)
+#define cputime64_to_jiffies64(__ct)	((__ct) * HZ / NSEC_PER_SEC)
+#define jiffies64_to_cputime64(__jif)	((__jif) * NSEC_PER_SEC / HZ)

It looks like cputime64_to_jiffies64 and cputime_to_jiffies will overflow at (((2^64 -1) / HZ) + 1) ns. In the case where HZ is 1000, this means it will overflow at (584/1000) years or about 213 days. Similarly for cputime_to_clock_t(). Is this a problem?

Quoted 93 lines
(quoted diff) +33 -17
 /*
  * Convert cputime <-> milliseconds
  */
-#define cputime_to_msecs(__ct)		jiffies_to_msecs(__ct)
-#define msecs_to_cputime(__msecs)	msecs_to_jiffies(__msecs)
+#define cputime_to_msecs(__ct)		((__ct) / NSEC_PER_MSEC)
+#define msecs_to_cputime(__msecs)	((__msecs) * NSEC_PER_MSEC)
 
 /*
  * Convert cputime <-> seconds
  */
-#define cputime_to_secs(__ct)		((__ct) / HZ)
-#define secs_to_cputime(__secs)		((__secs) * HZ)
-
-/*
- * Convert cputime <-> timespec
- */
-#define timespec_to_cputime(__val)	timespec_to_jiffies(__val)
-#define cputime_to_timespec(__ct,__val)	jiffies_to_timespec(__ct,__val)
+#define cputime_to_secs(__ct)		((__ct) / NSEC_PER_SEC)
+#define secs_to_cputime(__secs)		((__secs) * NSEC_PER_SEC)
 
 /*
- * Convert cputime <-> timeval
+ * Convert cputime <-> timespec (nsec)
  */
-#define timeval_to_cputime(__val)	timeval_to_jiffies(__val)
-#define cputime_to_timeval(__ct,__val)	jiffies_to_timeval(__ct,__val)
+static inline cputime_t timespec_to_cputime(struct timespec *val)
+{
+	cputime_t ret = val->tv_sec * NSEC_PER_SEC;
+	return (ret + val->tv_nsec);
+}
+static inline void cputime_to_timespec(const cputime_t ct, struct timespec *val)
+{
+	val->tv_sec  = ct / NSEC_PER_SEC;
+	val->tv_nsec = ct % NSEC_PER_SEC;
+}
+
+/*
+ * Convert cputime <-> timeval (msec)
+ */
+static inline cputime_t timeval_to_cputime(struct timeval *val)
+{
+	cputime_t ret = val->tv_sec * NSEC_PER_SEC;
+	return (ret + val->tv_usec * NSEC_PER_USEC);
+}
+static inline void cputime_to_timeval(const cputime_t ct, struct timeval *val)
+{
+	val->tv_sec = ct / NSEC_PER_SEC;
+	val->tv_usec = (ct % NSEC_PER_SEC) / NSEC_PER_USEC;
+}
 
 /*
- * Convert cputime <-> clock
+ * Convert cputime <-> clock (USER_HZ)
  */
-#define cputime_to_clock_t(__ct)	jiffies_to_clock_t(__ct)
-#define clock_t_to_cputime(__x)		clock_t_to_jiffies(__x)
+#define cputime_to_clock_t(__ct)	((__ct) * USER_HZ / NSEC_PER_SEC)
+#define clock_t_to_cputime(__x)		((__x) * NSEC_PER_SEC / USER_HZ)
 
 /*
  * Convert cputime64 to clock.
  */
-#define cputime64_to_clock_t(__ct)      jiffies_64_to_clock_t(__ct)
+#define cputime64_to_clock_t(__ct)      cputime_to_clock_t((cputime_t)__ct)
 
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING */
 #endif /* __IA64_CPUTIME_H */

Index: linux-2.6.23/arch/ia64/ia32/elfcore32.h =================================> --- linux-2.6.23.orig/arch/ia64/ia32/elfcore32.h +++ linux-2.6.23/arch/ia64/ia32/elfcore32.h

(quoted diff) +5 -1
@@ -30,7 +30,12 @@
 	int	si_errno;			/* errno */
 };
 
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+#define cputime_to_timeval(a,b) \
+	do { (b)->tv_usec = 0; (b)->tv_sec = (a)/NSEC_PER_SEC; } while(0)
+#else
 #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
+#endif
 
 struct elf_prstatus
 {
 
 
-

To unsubscribe from this list: send the line "unsubscribe linux-ia64" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 3 lines
Horms
  H: http://www.vergenet.net/~horms/
  W: http://www.valinux.co.jp/en/
#2 lore raw
In reply to Hidetoshi Seto
Quoted 10 lines · Simon Horman

Review

Quoted 4 lines · Hidetoshi Seto
(quoted diff) +4 -0
+#define cputime_to_jiffies(__ct)	((__ct) * HZ / NSEC_PER_SEC)
+#define jiffies_to_cputime(__jif)	((__jif) * NSEC_PER_SEC / HZ)
+#define cputime64_to_jiffies64(__ct)	((__ct) * HZ / NSEC_PER_SEC)
+#define jiffies64_to_cputime64(__jif)	((__jif) * NSEC_PER_SEC / HZ)

It looks like cputime64_to_jiffies64 and cputime_to_jiffies will overflow at (((2^64 -1) / HZ) + 1) ns. In the case where HZ is 1000, this means it will overflow at (584/1000) years or about 213 days. Similarly for cputime_to_clock_t(). Is this a problem?

Exactly.
I guess NSEC_PER_SEC is permanently 10^9, and larger HZ will not be required soon in this century. Does the following help us?

#define cputime64_to_jiffies64(__ct) ((__ct) / (NSEC_PER_SEC / HZ))
#define jiffies64_to_cputime64(__jif) ((__jif) * (NSEC_PER_SEC / HZ))

Thanks,
H.Seto

#3 lore raw
In reply to Hidetoshi Seto
Quoted 12 lines · Hidetoshi Seto
Quoted 10 lines · Simon Horman

Review

Quoted 4 lines · Hidetoshi Seto
(quoted diff) +4 -0
+#define cputime_to_jiffies(__ct)	((__ct) * HZ / NSEC_PER_SEC)
+#define jiffies_to_cputime(__jif)	((__jif) * NSEC_PER_SEC / HZ)
+#define cputime64_to_jiffies64(__ct)	((__ct) * HZ / NSEC_PER_SEC)
+#define jiffies64_to_cputime64(__jif)	((__jif) * NSEC_PER_SEC / HZ)

It looks like cputime64_to_jiffies64 and cputime_to_jiffies will overflow at (((2^64 -1) / HZ) + 1) ns. In the case where HZ is 1000, this means it will overflow at (584/1000) years or about 213 days. Similarly for cputime_to_clock_t(). Is this a problem?

Quoted 6 lines

Exactly.
I guess NSEC_PER_SEC is permanently 10^9, and larger HZ will not be required soon in this century. Does the following help us?

#define cputime64_to_jiffies64(__ct) ((__ct) / (NSEC_PER_SEC / HZ))
#define jiffies64_to_cputime64(__jif) ((__jif) * (NSEC_PER_SEC / HZ))

That does seem to be a lot better. I guess there might be some rounding strangeness if NSEC_PER_SEC is not an integer multiple of HZ, but as both cputime64_to_jiffies64() and jiffies64_to_cputime64() use the same rounded value, this shouldn't be a problem. Actually its probably not a problem at all.

I guess there is also now an assumption that HZ is much less than NSEC_PER_SEC, that also seems reasonable.

Signature · 3 lines
Horms
  H: http://www.vergenet.net/~horms/
  W: http://www.valinux.co.jp/en/