[Patch] sysinfo compatibility

From: Christoph Rohland (cr@sap.com)
Date: Tue Aug 21 2001 - 03:03:11 EST


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/



This archive was generated by hypermail 2b29 : Thu Aug 23 2001 - 21:00:40 EST