[Patch] sysinfo compatibility

Christoph Rohland (cr@sap.com)
21 Aug 2001 10:03:11 +0200


Hi Eric and Alan,

sysinfo does use a new mem_unit field if ram+swap > MAX_ULONG. That
breaks 2.2 compatibility for a lot machines.

I think it is more resonable to use the mem_unit field only if one of
ram or swap is bigger than MAX_ULONG. (And 2.2 was only broken in that
case)

The appended patch implements that (and makes the logic a little bit
easier)

Greetings
Christoph

diff -uNr 2.4.9/kernel/info.c 2.4.9-sysinfo/kernel/info.c
--- 2.4.9/kernel/info.c Sat Apr 21 01:15:40 2001
+++ 2.4.9-sysinfo/kernel/info.c Wed Jul 4 16:56:23 2001
@@ -16,6 +16,7 @@
asmlinkage long sys_sysinfo(struct sysinfo *info)
{
struct sysinfo val;
+ unsigned int mem_unit;

memset((char *)&val, 0, sizeof(struct sysinfo));

@@ -32,47 +33,36 @@
si_meminfo(&val);
si_swapinfo(&val);

- {
- unsigned long mem_total, sav_total;
- unsigned int mem_unit, bitcount;
-
- /* If the sum of all the available memory (i.e. ram + swap)
- * is less than can be stored in a 32 bit unsigned long then
- * we can be binary compatible with 2.2.x kernels. If not,
- * well, in that case 2.2.x was broken anyways...
- *
- * -Erik Andersen <andersee@debian.org> */
-
- mem_total = val.totalram + val.totalswap;
- if (mem_total < val.totalram || mem_total < val.totalswap)
- goto out;
- bitcount = 0;
- mem_unit = val.mem_unit;
- while (mem_unit > 1) {
- bitcount++;
- mem_unit >>= 1;
- sav_total = mem_total;
- mem_total <<= 1;
- if (mem_total < sav_total)
- goto out;
- }
-
- /* If mem_total did not overflow, multiply all memory values by
- * val.mem_unit and set it to 1. This leaves things compatible
- * with 2.2.x, and also retains compatibility with earlier 2.4.x
- * kernels... */
+ /*
+ * If the the available memory or swap is less than can be
+ * stored in a 32 bit unsigned long then we can be binary
+ * compatible with 2.2.x kernels. If not, well, in that case
+ * 2.2.x was broken anyways...
+ *
+ * -Erik Andersen <andersee@debian.org>
+ */
+
+ mem_unit = val.mem_unit;
+ if (val.totalram * mem_unit > val.totalram &&
+ val.totalswap * mem_unit > val.totalswap) {
+
+ /*
+ * If mem_total did not overflow, multiply all memory
+ * values by val.mem_unit and set it to 1. This
+ * leaves things compatible with 2.2.x, and also
+ * retains compatibility with earlier 2.4.x kernels...
+ */

val.mem_unit = 1;
- val.totalram <<= bitcount;
- val.freeram <<= bitcount;
- val.sharedram <<= bitcount;
- val.bufferram <<= bitcount;
- val.totalswap <<= bitcount;
- val.freeswap <<= bitcount;
- val.totalhigh <<= bitcount;
- val.freehigh <<= bitcount;
+ val.totalram *= mem_unit;
+ val.freeram *= mem_unit;
+ val.sharedram *= mem_unit;
+ val.bufferram *= mem_unit;
+ val.totalswap *= mem_unit;
+ val.freeswap *= mem_unit;
+ val.totalhigh *= mem_unit;
+ val.freehigh *= mem_unit;
}
-out:
if (copy_to_user(info, &val, sizeof(struct sysinfo)))
return -EFAULT;
return 0;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/