[BusyBox] bug#1071: check_free_memory() on Linux 2.4.0 (again)
Larry Doolittle
ldoolitt at recycle.lbl.gov
Thu Nov 2 00:53:41 UTC 2000
Package: busybox
Version: 0.47
Severity: normal
The check_free_memory routine in init.c gets the wrong answer on
Linux kernel 2.4.0test4. The code looks bogus for other versions,
too. The attached patch is definitely clean for 2.4.0-test4,
2.4.0-test9, and I believe 2.0.x as well. I don't know about 2.2.x.
This is my second stab at nailing this bug, I think you'll like
this one much better.
Testing on a StrongARM with 32M of RAM:
Printout from linux-2.4.0-test4:
check_free_memory: ( 7749 + 0 ) * 4096 / 1024 -> 30996
Printout from linux-2.4.0-test9:
check_free_memory: ( 31662080 + 0 ) * 1 / 1024 -> 30920
I hope this goes in!
- Larry Doolittle <LRDoolittle at lbl.gov>
--- busybox-0.47/init.c Mon Sep 25 14:42:27 2000
+++ busybox-0.47-lrd/init.c Wed Nov 1 16:48:21 2000
@@ -288,30 +288,29 @@
tcsetattr(fd, TCSANOW, &tty);
}
-/* How much memory does this machine have? */
+/* How much memory does this machine have?
+ Units are kBytes to avoid overflow on 4GB machines */
static int check_free_memory()
{
struct sysinfo info;
+ unsigned int result, u, s=10;
+
- /* Pre initialize mem_unit in case this kernel is something prior to
- * the linux 2.4 kernel (which will actually fill in mem_unit... */
- sysinfo(&info);
if (sysinfo(&info) != 0) {
printf("Error checking free memory: %s\n", strerror(errno));
return -1;
}
- /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */
- if (info.mem_unit==0) {
- info.mem_unit=1;
- }
- info.mem_unit*=1024;
-
- /* Note: These values can in theory overflow a 32 bit unsigned long (i.e.
- * mem >= Gib), but who puts more then 4GiB ram+swap on an embedded
- * system? */
- info.totalram/=info.mem_unit;
- info.totalswap/=info.mem_unit;
- return(info.totalram+info.totalswap);
+
+ /* Kernels 2.0.x return info.mem_unit==0, and values in bytes.
+ * Kernels 2.4.0 return info.mem_unit in bytes.
+ * Someone else will have to test this on 2.2.x */
+ u = info.mem_unit;
+ if (u==0) u=1;
+ while ( (u&1) == 0 && s > 0 ) { u>>=1; s--; }
+ result = (info.totalram>>s) + (info.totalswap>>s);
+ result = result*u;
+ if (result < 0) result = INT_MAX;
+ return result;
}
static void console_init()
More information about the busybox
mailing list