patch-2.4.4 linux/kernel/info.c

Next file: linux/kernel/ksyms.c
Previous file: linux/kernel/fork.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/kernel/info.c linux/kernel/info.c
@@ -33,41 +33,46 @@
 	si_swapinfo(&val);
 
 	{
-		/* If the sum of all the available memory (i.e. ram + swap +
-		 * highmem) is less then can be stored in a 32 bit unsigned long
-		 * then we can be binary compatible with 2.2.x kernels.  If not,
-		 * well, who cares since in that case 2.2.x was broken anyways...
+		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> */
 
-		unsigned long mem_total = val.totalram + val.totalswap;
-		if ( !(mem_total < val.totalram || mem_total < val.totalswap)) {
-			unsigned long mem_total2 = mem_total + val.totalhigh; 
-			if (!(mem_total2 < mem_total || mem_total2 < val.totalhigh))
-			{
-				/* If mem_total did not overflow.  Divide all memory values by
-				 * mem_unit and set mem_unit=1.  This leaves things compatible with
-				 * 2.2.x, and also retains compatibility with earlier 2.4.x
-				 * kernels...  */
-
-				int bitcount = 0;
-				while (val.mem_unit > 1) 
-				{
-					bitcount++;
-					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;
-			}
+		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...  */
+
+		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;
+	}
+out:
 	if (copy_to_user(info, &val, sizeof(struct sysinfo)))
 		return -EFAULT;
 	return 0;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)