Greetings, I posted the following to the new linux-ia64@vger.kernel.org list on 16-June before many of you were subscribed. I haven't seen a response yet so I'm reposting on the assumption that it may not have been noticed due to the mailing list transition. sysinfo(2) called from a 32-bit application does not return correct system information values when memory or swap exceeds 32 bits. On a system with with 8 GB of physical memory the output of 32-bit and 64-bit versions of the below program is: 32-bit: totalram 4155506688, f7b00000, sizeof(4) freeram 3901259776, e8888000, sizeof(4) sharedram 0, 0, sizeof(4) bufferram 21364736, 1460000, sizeof(4) totalswap 1077411840, 40380000, sizeof(4) freeswap 1077411840, 40380000, sizeof(4) mem_unit 1, sizeof(4) 64-bit: totalram 8450473984, 1f7b00000, sizeof(8) freeram 8196145152, 1e8874000, sizeof(8) sharedram 0, 0, sizeof(8) bufferram 21364736, 1460000, sizeof(8) totalswap 1077411840, 40380000, sizeof(8) freeswap 1077411840, 40380000, sizeof(8) mem_unit 1, sizeof(4) Note the discrepancies in the values displayed by the 32-bit application. e.g. the totalram value indicates that only 4 GB of memory is present. The additional code in the below patch scales the data to provide more reasonable values. 32-bit: totalram 515776, 7dec0, sizeof(4) freeram 187082, 2daca, sizeof(4) sharedram 0, 0, sizeof(4) bufferram 27825, 6cb1, sizeof(4) totalswap 65760, 100e0, sizeof(4) freeswap 65760, 100e0, sizeof(4) mem_unit 16384, sizeof(4) 64-bit: totalram 8450473984, 1f7b00000, sizeof(8) freeram 3065069568, b6b14000, sizeof(8) sharedram 0, 0, sizeof(8) bufferram 455884800, 1b2c4000, sizeof(8) totalswap 1077411840, 40380000, sizeof(8) freeswap 1077411840, 40380000, sizeof(8) mem_unit 1, sizeof(4) The patch should apply cleanly to the 2.4 ia64 bk tree. 2.5 also needs the fix. Thanks, Gary -- Gary Hade IBM Linux Technology Center 503-578-4503 IBM T/L: 775-4503 garyhade@us.ibm.com http://www.ibm.com/linux/ltc #include <stdlib.h> #include <stdio.h> #include <sys/sysinfo.h> #include <unistd.h> int main (int argc, char *argv[]) { struct sysinfo sstats; sysinfo(&sstats); printf(" totalram %lu, %lx, sizeof(%d)\n", sstats.totalram, sstats.totalram, sizeof(sstats.totalram)); printf(" freeram %lu, %lx, sizeof(%d)\n", sstats.freeram, sstats.freeram, sizeof(sstats.freeram)); printf(" sharedram %lu, %lx, sizeof(%d)\n", sstats.sharedram, sstats.sharedram, sizeof(sstats.sharedram)); printf(" bufferram %lu, %lx, sizeof(%d)\n", sstats.bufferram, sstats.bufferram, sizeof(sstats.bufferram)); printf(" totalswap %lu, %lx, sizeof(%d)\n", sstats.totalswap, sstats.totalswap, sizeof(sstats.totalswap)); printf(" freeswap %lu, %lx, sizeof(%d)\n", sstats.freeswap, sstats.freeswap, sizeof(sstats.freeswap)); printf(" mem_unit %u, sizeof(%d)\n", sstats.mem_unit, sizeof(sstats.mem_unit)); return 0; } --- linux-ia64-2.4/arch/ia64/ia32/sys_ia32.c Thu Jun 12 18:15:18 2003 +++ linux-ia64-2.4-sysinfofx/arch/ia64/ia32/sys_ia32.c Thu Jun 12 18:17:59 2003 @@ -3729,10 +3729,29 @@ mm_segment_t old_fs = get_fs(); struct sysinfo s; long ret, err; + int bitcount = 0; set_fs(KERNEL_DS); ret = sys_sysinfo(&s); set_fs(old_fs); + + /* Check to see if any memory value is too large for 32-bit and scale + * down if needed + */ + if ((s.totalram >> 32) || (s.totalswap >> 32)) { + while (s.mem_unit < PAGE_SIZE) { + s.mem_unit <<= 1; + bitcount++; + } + s.totalram >>= bitcount; + s.freeram >>= bitcount; + s.sharedram >>= bitcount; + s.bufferram >>= bitcount; + s.totalswap >>= bitcount; + s.freeswap >>= bitcount; + s.totalhigh >>= bitcount; + s.freehigh >>= bitcount; + } if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) return -EFAULT; - To unsubscribe from this list: send the line "unsubscribe linux-ia64" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.htmlReceived on Mon Jun 23 13:04:37 2003
This archive was generated by hypermail 2.1.8 : 2005-08-02 09:20:15 EST