All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] linux-user: Implement starttime field in self stat emulation
@ 2022-01-25  2:47 Cameron Esfahani
  2022-01-25  9:41 ` Laurent Vivier
  0 siblings, 1 reply; 3+ messages in thread
From: Cameron Esfahani @ 2022-01-25  2:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Instead of always returning 0, return actual starttime.

Signed-off-by: Cameron Esfahani <dirty@apple.com>
---
 linux-user/syscall.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5950222a77..59265ab986 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8107,6 +8107,34 @@ static int open_self_stat(void *cpu_env, int fd)
         } else if (i == 3) {
             /* ppid */
             g_string_printf(buf, FMT_pid " ", getppid());
+        } else if (i == 21) {
+            /* starttime */
+            FILE *fp = NULL;
+            char *line = NULL;
+            char *skipped_comm = NULL;
+            size_t n = 0;
+            unsigned long long starttime = 0;
+
+            fp = fopen("/proc/self/stat", "r");
+            if (fp) {
+                if (getdelim(&line, &n, '\0', fp) != -1) {
+                    /* Find end of comm field */
+                    skipped_comm = strrchr(line, ')');
+                    if (skipped_comm != NULL) {
+                        /* Skip over parenthesis and space */
+                        skipped_comm += 2;
+                        /* Scan starttime (field 20 after pid and comm) */
+                        (void) sscanf(skipped_comm, "%*c %*d %*d %*d %*d %*d "
+                                            "%*u %*u %*u %*u %*u %*u %*u %*d "
+                                            "%*d %*d %*d %*d %*d %llu",
+                                            &starttime);
+                    }
+                    free(line);
+                }
+                fclose(fp);
+            }
+
+            g_string_printf(buf, "%llu ", starttime);
         } else if (i == 27) {
             /* stack bottom */
             g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);
-- 
2.32.0 (Apple Git-131)



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] linux-user: Implement starttime field in self stat emulation
  2022-01-25  2:47 [PATCH] linux-user: Implement starttime field in self stat emulation Cameron Esfahani
@ 2022-01-25  9:41 ` Laurent Vivier
  2022-01-25 10:12   ` Laurent Vivier
  0 siblings, 1 reply; 3+ messages in thread
From: Laurent Vivier @ 2022-01-25  9:41 UTC (permalink / raw)
  To: Cameron Esfahani, qemu-devel

Le 25/01/2022 à 03:47, Cameron Esfahani a écrit :
> Instead of always returning 0, return actual starttime.
> 
> Signed-off-by: Cameron Esfahani <dirty@apple.com>
> ---
>   linux-user/syscall.c | 28 ++++++++++++++++++++++++++++
>   1 file changed, 28 insertions(+)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 5950222a77..59265ab986 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8107,6 +8107,34 @@ static int open_self_stat(void *cpu_env, int fd)
>           } else if (i == 3) {
>               /* ppid */
>               g_string_printf(buf, FMT_pid " ", getppid());
> +        } else if (i == 21) { > +            /* starttime */
> +            FILE *fp = NULL;
> +            char *line = NULL;
> +            char *skipped_comm = NULL;
> +            size_t n = 0;
> +            unsigned long long starttime = 0;
> +
> +            fp = fopen("/proc/self/stat", "r");
> +            if (fp) {
> +                if (getdelim(&line, &n, '\0', fp) != -1) {
> +                    /* Find end of comm field */
> +                    skipped_comm = strrchr(line, ')');
> +                    if (skipped_comm != NULL) {
> +                        /* Skip over parenthesis and space */
> +                        skipped_comm += 2;
> +                        /* Scan starttime (field 20 after pid and comm) */
> +                        (void) sscanf(skipped_comm, "%*c %*d %*d %*d %*d %*d "
> +                                            "%*u %*u %*u %*u %*u %*u %*u %*d "
> +                                            "%*d %*d %*d %*d %*d %llu",
> +                                            &starttime);
> +                    }
> +                    free(line);
> +                }
> +                fclose(fp);
> +            }
> +
> +            g_string_printf(buf, "%llu ", starttime);

According to the kernel code:

   start_time = nsec_to_clock_t(timens_add_boottime_ns(task->start_boottime));

(timens_add_boottime_ns() is to adjust time offset according to the namespace)
(nsec_to_clock_t() is "div_u64(x, NSEC_PER_SEC / USER_HZ);")

and

   p->start_boottime = ktime_get_boottime_ns();
...
   static inline u64 ktime_get_boottime_ns(void)
   {
           return ktime_to_ns(ktime_get_boottime());
   }
...
   /**
    * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
    *
    * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
    * time spent in suspend.
    */
   static inline ktime_t ktime_get_boottime(void)
   {
           return ktime_get_with_offset(TK_OFFS_BOOT);
   }

So I think rather than scanning /proc/self/stat you could use clock_gettime(CLOCK_BOOTTIME, ...) to 
get the value.

https://linux.die.net/man/2/clock_gettime

CLOCK_BOOTTIME (since Linux 2.6.39; Linux-specific)

	Identical to CLOCK_MONOTONIC, except it also includes any time that the system is suspended.
	This allows applications to get a suspend-aware monotonic clock without having to deal with
	the complications of CLOCK_REALTIME, which may have discontinuities if the time is changed
	using settimeofday(2).

https://man7.org/linux/man-pages/man5/proc.5.html

    /proc/[pid]/stat
...
	(22) starttime  %llu

		The time the process started after system boot.  In
                 kernels before Linux 2.6, this value was expressed
                 in jiffies.  Since Linux 2.6, the value is
                 expressed in clock ticks (divide by
                 sysconf(_SC_CLK_TCK)).

                 The format for this field was %lu before Linux 2.6.

>           } else if (i == 27) {
>               /* stack bottom */
>               g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);

Thanks,
Laurent


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] linux-user: Implement starttime field in self stat emulation
  2022-01-25  9:41 ` Laurent Vivier
@ 2022-01-25 10:12   ` Laurent Vivier
  0 siblings, 0 replies; 3+ messages in thread
From: Laurent Vivier @ 2022-01-25 10:12 UTC (permalink / raw)
  To: qemu-devel

Le 25/01/2022 à 10:41, Laurent Vivier a écrit :
> Le 25/01/2022 à 03:47, Cameron Esfahani a écrit :
>> Instead of always returning 0, return actual starttime.
>>
>> Signed-off-by: Cameron Esfahani <dirty@apple.com>
>> ---
>>   linux-user/syscall.c | 28 ++++++++++++++++++++++++++++
>>   1 file changed, 28 insertions(+)
>>
>> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
>> index 5950222a77..59265ab986 100644
>> --- a/linux-user/syscall.c
>> +++ b/linux-user/syscall.c
>> @@ -8107,6 +8107,34 @@ static int open_self_stat(void *cpu_env, int fd)
>>           } else if (i == 3) {
>>               /* ppid */
>>               g_string_printf(buf, FMT_pid " ", getppid());
>> +        } else if (i == 21) { > +            /* starttime */
>> +            FILE *fp = NULL;
>> +            char *line = NULL;
>> +            char *skipped_comm = NULL;
>> +            size_t n = 0;
>> +            unsigned long long starttime = 0;
>> +
>> +            fp = fopen("/proc/self/stat", "r");
>> +            if (fp) {
>> +                if (getdelim(&line, &n, '\0', fp) != -1) {
>> +                    /* Find end of comm field */
>> +                    skipped_comm = strrchr(line, ')');
>> +                    if (skipped_comm != NULL) {
>> +                        /* Skip over parenthesis and space */
>> +                        skipped_comm += 2;
>> +                        /* Scan starttime (field 20 after pid and comm) */
>> +                        (void) sscanf(skipped_comm, "%*c %*d %*d %*d %*d %*d "
>> +                                            "%*u %*u %*u %*u %*u %*u %*u %*d "
>> +                                            "%*d %*d %*d %*d %*d %llu",
>> +                                            &starttime);
>> +                    }
>> +                    free(line);
>> +                }
>> +                fclose(fp);
>> +            }
>> +
>> +            g_string_printf(buf, "%llu ", starttime);
> 
> According to the kernel code:
> 
>    start_time = nsec_to_clock_t(timens_add_boottime_ns(task->start_boottime));
> 
> (timens_add_boottime_ns() is to adjust time offset according to the namespace)
> (nsec_to_clock_t() is "div_u64(x, NSEC_PER_SEC / USER_HZ);")
> 
> and
> 
>    p->start_boottime = ktime_get_boottime_ns();
> ...
>    static inline u64 ktime_get_boottime_ns(void)
>    {
>            return ktime_to_ns(ktime_get_boottime());
>    }
> ...
>    /**
>     * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
>     *
>     * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
>     * time spent in suspend.
>     */
>    static inline ktime_t ktime_get_boottime(void)
>    {
>            return ktime_get_with_offset(TK_OFFS_BOOT);
>    }
> 
> So I think rather than scanning /proc/self/stat you could use clock_gettime(CLOCK_BOOTTIME, ...) to 
> get the value.
> 
> https://linux.die.net/man/2/clock_gettime
> 
> CLOCK_BOOTTIME (since Linux 2.6.39; Linux-specific)
> 
>      Identical to CLOCK_MONOTONIC, except it also includes any time that the system is suspended.
>      This allows applications to get a suspend-aware monotonic clock without having to deal with
>      the complications of CLOCK_REALTIME, which may have discontinuities if the time is changed
>      using settimeofday(2).
> 
> https://man7.org/linux/man-pages/man5/proc.5.html
> 
>     /proc/[pid]/stat
> ...
>      (22) starttime  %llu
> 
>          The time the process started after system boot.  In
>                  kernels before Linux 2.6, this value was expressed
>                  in jiffies.  Since Linux 2.6, the value is
>                  expressed in clock ticks (divide by
>                  sysconf(_SC_CLK_TCK)).
> 
>                  The format for this field was %lu before Linux 2.6.
> 
>>           } else if (i == 27) {
>>               /* stack bottom */
>>               g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);
> 

and we could add a field in TaskState (start_boottime) to set the bootime value in init_task_state() 
when the task is started and to read it in open_self_stat().

Thanks,
Laurent





^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-01-25 10:20 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-25  2:47 [PATCH] linux-user: Implement starttime field in self stat emulation Cameron Esfahani
2022-01-25  9:41 ` Laurent Vivier
2022-01-25 10:12   ` Laurent Vivier

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.