akaros/kern/include/ros/procinfo.h
<<
>>
Prefs
   1/* See COPYRIGHT for copyright information. */
   2
   3#pragma once
   4
   5#include <ros/memlayout.h>
   6#include <ros/common.h>
   7#include <ros/resource.h>
   8#include <ros/atomic.h>
   9#include <ros/arch/arch.h>
  10#include <ros/cpu_feat.h>
  11#include <string.h>
  12
  13/* Process creation flags */
  14#define PROC_DUP_FGRP                   1
  15
  16#define PROCINFO_MAX_ARGP 32
  17#define PROCINFO_ARGBUF_SIZE 3072
  18
  19#ifdef ROS_KERNEL
  20#include <sys/queue.h>
  21#endif /* ROS_KERNEL */
  22
  23/* Not necessary to expose all of this, but it doesn't hurt, and is convenient
  24 * for the kernel.  Need to do some acrobatics for the TAILQ_ENTRY. */
  25struct vcore;
  26struct vcore {
  27#ifdef ROS_KERNEL
  28        TAILQ_ENTRY(vcore)              list;
  29#else /* userspace */
  30        void                            *dummy_ptr1;
  31        void                            *dummy_ptr2;
  32#endif /* ROS_KERNEL */
  33        uint32_t                        pcoreid;
  34        bool                            valid;
  35        /* these two differ when a preempt is in flight. */
  36        uint32_t                        nr_preempts_sent;
  37        uint32_t                        nr_preempts_done;
  38        uint64_t                        preempt_pending;
  39        /* A process can see cumulative runtime as of the last resume, and can
  40         * also calculate runtime in this interval, by adding (ns - resume) +
  41         * total. */
  42        uint64_t                        resume_ticks;   /* TSC at resume time */
  43        /* ticks up to last offlining */
  44        uint64_t                        total_ticks;
  45};
  46
  47struct pcore {
  48        uint32_t                        vcoreid;
  49        bool                            valid;
  50};
  51
  52typedef struct procinfo {
  53        pid_t pid;
  54        pid_t ppid;
  55        size_t max_vcores;      /* TODO: change to a uint32_t */
  56        uint64_t tsc_freq;
  57        uint64_t timing_overhead;
  58        uintptr_t program_end;
  59        /* glibc relies on stuff above this point.  if you change it, you need
  60         * to rebuild glibc. */
  61        bool is_mcp;                    /* is in multi mode */
  62        unsigned long                   res_grant[MAX_NUM_RESOURCES];
  63        struct vcore                    vcoremap[MAX_NUM_CORES];
  64        uint32_t                        num_vcores;
  65        struct pcore                    pcoremap[MAX_NUM_CORES];
  66        seq_ctr_t                       coremap_seqctr;
  67} procinfo_t;
  68#define PROCINFO_NUM_PAGES  ((sizeof(procinfo_t)-1)/PGSIZE + 1)
  69
  70/* We align this so that the kernel can easily allocate it in the BSS */
  71struct proc_global_info {
  72        unsigned long cpu_feats[__NR_CPU_FEAT_BITS];
  73        uint64_t x86_default_xcr0;
  74        uint64_t tsc_freq;
  75        uint64_t tsc_overhead;
  76        uint64_t bus_freq;
  77        uint64_t walltime_ns_last;
  78        uint64_t tsc_cycles_last;
  79} __attribute__((aligned(PGSIZE)));
  80#define PROCGINFO_NUM_PAGES  (sizeof(struct proc_global_info) / PGSIZE)
  81
  82#ifdef ROS_KERNEL
  83
  84/* defined in init.c */
  85extern struct proc_global_info __proc_global_info;
  86
  87#else /* Userland */
  88
  89#define __procinfo (*(procinfo_t*)UINFO)
  90#define __proc_global_info (*(struct proc_global_info*)UGINFO)
  91
  92#include <ros/common.h>
  93#include <ros/atomic.h>
  94#include <ros/syscall.h>
  95
  96/* Figure out what your vcoreid is from your pcoreid and procinfo.  Only low
  97 * level or debugging code should call this. */
  98static inline uint32_t __get_vcoreid_from_procinfo(void)
  99{
 100        /* The assumption is that any IPIs/KMSGs would knock userspace into the
 101         * kernel before it could read the closing of the seqctr.  Put another
 102         * way, there is a 'memory barrier' between the IPI write and the seqctr
 103         * write.  I think this is true. */
 104        uint32_t kpcoreid, kvcoreid;
 105        extern long __ros_syscall_noerrno(unsigned int _num, long _a0, long _a1,
 106                                          long _a2, long _a3, long _a4,
 107                                          long _a5);
 108
 109        seq_ctr_t old_seq;
 110        do {
 111                cmb();
 112                old_seq = __procinfo.coremap_seqctr;
 113                kpcoreid = __ros_syscall_noerrno(SYS_getpcoreid, 0, 0, 0, 0, 0,
 114                                                 0);
 115                if (!__procinfo.pcoremap[kpcoreid].valid)
 116                        continue;
 117                kvcoreid = __procinfo.pcoremap[kpcoreid].vcoreid;
 118        } while (seqctr_retry(old_seq, __procinfo.coremap_seqctr));
 119        return kvcoreid;
 120}
 121
 122static inline uint32_t __get_vcoreid(void)
 123{
 124        /* since sys_getvcoreid could lie (and might never change) */
 125        return __get_vcoreid_from_procinfo();
 126}
 127
 128#endif /* ifndef ROS_KERNEL */
 129