cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cpu-load.rst (2767B)


      1========
      2CPU 负载
      3========
      4
      5Linux通过``/proc/stat``和``/proc/uptime``导出各种信息,用户空间工具
      6如top(1)使用这些信息计算系统花费在某个特定状态的平均时间。
      7例如:
      8
      9    $ iostat
     10    Linux 2.6.18.3-exp (linmac)     02/20/2007
     11
     12    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
     13              10.01    0.00    2.92    5.44    0.00   81.63
     14
     15    ...
     16
     17这里系统认为在默认采样周期內有10.01%的时间工作在用户空间,2.92%的时
     18间用在系统空间,总体上有81.63%的时间是空闲的。
     19
     20大多数情况下``/proc/stat``的信息几乎真实反映了系统信息,然而,由于内
     21核采集这些数据的方式/时间的特点,有时这些信息根本不可靠。
     22
     23那么这些信息是如何被搜集的呢?每当时间中断触发时,内核查看此刻运行的
     24进程类型,并增加与此类型/状态进程对应的计数器的值。这种方法的问题是
     25在两次时间中断之间系统(进程)能够在多种状态之间切换多次,而计数器只
     26增加最后一种状态下的计数。
     27
     28举例
     29---
     30
     31假设系统有一个进程以如下方式周期性地占用cpu::
     32
     33     两个时钟中断之间的时间线
     34    |-----------------------|
     35     ^                     ^
     36     |_ 开始运行           |
     37                           |_ 开始睡眠
     38                           (很快会被唤醒)
     39
     40在上面的情况下,根据``/proc/stat``的信息(由于当系统处于空闲状态时,
     41时间中断经常会发生)系统的负载将会是0
     42
     43大家能够想象内核的这种行为会发生在许多情况下,这将导致``/proc/stat``
     44中存在相当古怪的信息::
     45
     46	/* gcc -o hog smallhog.c */
     47	#include <time.h>
     48	#include <limits.h>
     49	#include <signal.h>
     50	#include <sys/time.h>
     51	#define HIST 10
     52
     53	static volatile sig_atomic_t stop;
     54
     55	static void sighandler (int signr)
     56	{
     57	(void) signr;
     58	stop = 1;
     59	}
     60	static unsigned long hog (unsigned long niters)
     61	{
     62	stop = 0;
     63	while (!stop && --niters);
     64	return niters;
     65	}
     66	int main (void)
     67	{
     68	int i;
     69	struct itimerval it = { .it_interval = { .tv_sec = 0, .tv_usec = 1 },
     70				.it_value = { .tv_sec = 0, .tv_usec = 1 } };
     71	sigset_t set;
     72	unsigned long v[HIST];
     73	double tmp = 0.0;
     74	unsigned long n;
     75	signal (SIGALRM, &sighandler);
     76	setitimer (ITIMER_REAL, &it, NULL);
     77
     78	hog (ULONG_MAX);
     79	for (i = 0; i < HIST; ++i) v[i] = ULONG_MAX - hog (ULONG_MAX);
     80	for (i = 0; i < HIST; ++i) tmp += v[i];
     81	tmp /= HIST;
     82	n = tmp - (tmp / 3.0);
     83
     84	sigemptyset (&set);
     85	sigaddset (&set, SIGALRM);
     86
     87	for (;;) {
     88		hog (n);
     89		sigwait (&set, &i);
     90	}
     91	return 0;
     92	}
     93
     94
     95参考
     96---
     97
     98- https://lore.kernel.org/r/loom.20070212T063225-663@post.gmane.org
     99- Documentation/filesystems/proc.rst (1.8)
    100
    101
    102谢谢
    103---
    104
    105Con Kolivas, Pavel Machek