| I have a version of free I wrote for BusyBox that uses sysinfo (rather then |
| /proc) to get its information. Under 2.2.x it reports normal stuff, i.e. |
| [andersen@dillweed busybox]$ ./free |
| total used free shared buffers |
| Mem: 127800 124268 3532 16956 7544 |
| Swap: 128516 13584 114932 |
| Total: 256316 137852 118464 |
| |
| while under 2.2.0-test1-ac7 it reports wierd numbers (~ #/4096) |
| [andersen@dillweed busybox]$ ./free |
| total used free shared buffers |
| Mem: 30 11 19 0 1 |
| Swap: 31 0 31 |
| Total: 61 11 50 |
| |
| After investigating the problem, it turns out that somewhere during 2.3.x the |
| values for memory stored in struct sysinfo changed from being stored as bytes |
| to being units of PAGE_SIZE, but kernel/info.c was never updated to reflect |
| this change in definition. |
| |
| Breaking free isn't that big of a deal, but I also use sysinfo in init to check |
| that the box has enough ram from within the init process (and no, mounting |
| /proc from within init and reading /proc/meminfo is not a good solution. |
| BusyBox is often used in embedded systems where /proc is not compiled in). |
| |
| The following patch reinstates the traditional sysinfo(2) interface by |
| returning bytes (not units of PAGE_SIZE) for memory values. |
| |
| An additional patch suggestion (not included here) would be to eliminate the |
| supurfluous "mem_unit" variable from struct_sysinfo in include/linux/kernel.h |
| and arch/*/mm/init.c. |
| |
| -Erik |
| |
| -- |
| Erik B. Andersen Web: http://www.xmission.com/~andersen/ |
| email: andersee@debian.org |
| --This message was written using 73% post-consumer electrons-- |
| |
| --- linux/kernel/info.c.orig Mon Aug 23 12:15:53 1999 |
| +++ linux/kernel/info.c Sun Jun 4 01:13:11 2000 |
| @@ -2,6 +2,8 @@ |
| * linux/kernel/info.c |
| * |
| * Copyright (C) 1992 Darren Senn |
| + * Fixed to once again return bytes instead of page counts, |
| + * June 2000, by Erik Andersen <andersee@debian.org> |
| */ |
| |
| /* This implements the sysinfo() system call */ |
| @@ -10,7 +12,6 @@ |
| #include <linux/unistd.h> |
| #include <linux/swap.h> |
| #include <linux/smp_lock.h> |
| - |
| #include <asm/uaccess.h> |
| |
| asmlinkage long sys_sysinfo(struct sysinfo *info) |
| @@ -31,6 +32,17 @@ |
| |
| si_meminfo(&val); |
| si_swapinfo(&val); |
| + |
| + /* These are in units of PAGE_SIZE, but this interface |
| + * has always returned bytes. Make it return bytes */ |
| + val.totalram*=PAGE_SIZE; |
| + val.freeram*=PAGE_SIZE; |
| + val.sharedram*=PAGE_SIZE; |
| + val.bufferram*=PAGE_SIZE; |
| + val.totalswap*=PAGE_SIZE; |
| + val.freeswap*=PAGE_SIZE; |
| + val.totalhigh*=PAGE_SIZE; |
| + val.freehigh*=PAGE_SIZE; |
| |
| if (copy_to_user(info, &val, sizeof(struct sysinfo))) |
| return -EFAULT; |
| |