Distribution: Debian testing Hardware Environment: TP 600X Software Environment: preemptible kernel (in case that matters) Problem Description: In X windows (in an emacs shell or an xterm), cat /proc/acpi/debug_level produces $ cat /proc/acpi/debug_level Description Hex SET ACPI_LV_ERROR 0x00000001 [*] ACPI_LV_WARN 0x00000002 [*] ACPI_LV_INIT 0x00000004 [*] ACPI_LV_DEBUG_OBJECT 0x00000008 [*] ACPI_LV_INFO 0x00000010 [*] ACPI_LV_INIT_NAMES 0x00000020 [ ] ACPI_LV_PARSE 0x00000040 [ ] ACPI_LV_LOAD 0x00000080 [ ] ACPI_LV_DISPATCH 0x00000100 [ ] ACPI_LV_EXEC 0x00000200 [ ] ACPI_LV_NAMES 0x00000400 [ ] ACPI_LV_OPREGION 0x00000800 [ ] ACPI_LV_BFIELD 0x00001000 [ ] ACPI_LV_TABLES 0x00002000 [ ] ACPI_LV_VALUES 0x00004000 [ ] ACPI_LV_OBJECTS 0x00008000 [ ] ACPI_LV_RESOURCES 0x00010000 [ ] ACPI_LV_USER_REQUESTS 0x00020000 [ ] ACPI_LV_PACKAGE 0x00040000 [ ] ACPI_LV_ALLOCATIONS 0x00100000 [ ] ACPI_LV_FUNCTIONS 0x00200000 [ ] ACPI_LV_OPTIMIZATIONS 0x00400000 [ ] ACPI_LV_MUTEX 0x01000000 [ ] ACPI_LV_THREADS 0x02000000 [*]$ (the $ at the end is the shell prompt). Cutting and pasting the output to a file and doing 'wc' gives: 24 93 1024 /tmp/junkfile So it looks like 'cat' reads one 1024-byte block, and then gets an eof. But 'cat /proc/acpi/debug_level > somefile' works fine, as does 'cat /proc/acpi/debug_level | cat', and as does 'cat /proc/acpi/debug_level' in a vga console Steps to reproduce: To see an extreme case, run this C program (try with no arguments), which reads 1 byte at a time. For me it produces 'D' (the first letter of the column header 'Description'). As a check, trying it on /usr/share/dict/words works or on /proc/cmdline works fine; and trying it on /proc/acpi/debug_layer does not work. #include <stdio.h> #include <fcntl.h> /* usage: readit [file [bytes-at-a-time]] file defaults to /proc/acpi/debug_level, bytes-at-a-time to 1 */ int main (int argc, char **argv) { int fd, bytes, n = 1; char buf[10000], *name; name = argc > 1 ? argv[1] : "/proc/acpi/debug_level"; if (argc > 2) n = atoi (argv[2]); if ((fd = open(name, O_RDONLY)) == -1) { perror("readit: open()"); exit(1); } while ((bytes = read (fd, buf, n)) > 0) write (1, buf, bytes); if (bytes == -1) { perror("readit: read()"); exit(2); } if (close (fd) == -1) { perror("readit: close()"); exit(3); } return 0; }
Hmmm, I don't recall seeting this in earlier kernels -- did you notice at what kernel release /proc/acpi/debug_level broke?
I've noticed it on and off with several kernels, but never pinned it down until now. I just tried 2.6.11.4, the earliest 2.6 kernel that I have lying around, and it shows the same problem. Are there earlier kernels worth trying?
Created attachment 5653 [details] patch to fix reading from debug_level and debug_layer The attached patch fixes the problem for me. The problem happens if the first read asks for fewer bytes than the size of the answer, e.g. if you read 1 byte at a time. The second read will then arrive at acpi_system_read_debug() with offset=1. The test at the top (off != 0) then skips to the 'end:' label, which sets *eof=1 (and sets size=0). So the code reading from /proc/acpi/debug_level (or debug_layer) will get 1 byte and then an eof. The fix is to delete the (off != 0) test, and recompute the answer from scratch each time, returning whatever piece of it the user wants. Probably 'cat /proc/acpi/debug_level | cat' worked fine because cat increases its buffer size to 4096 (big enough) when its stdout is not a tty, otherwise it uses 1024: $ strace -eread cat /proc/acpi/debug_level | cat ... read(3, "Description \tHex "..., 4096) = 1313 ... but (showing the problem): $ strace -eread cat /proc/acpi/debug_level ... read(3, "Description \tHex "..., 1024) = 1024 ... Another problem could happen on a machine with small pages (1024 bytes or less), because then the answer would overflow the allocated page passed in 'page' (on this kernel, the answer has 1313 bytes).
Updated kernel version to 2.6.15, which I just tested and it has the same problem.
Created attachment 8846 [details] new model of ACPI debug interface This patach is to build a new model of ACPI debug interface by using seq_file helper functions for making synthetic files from sequences of records. This can successfully reduce the potential problems brought by the former model which do all the fallible operations itself.
a change of plan: Rui created these files under /sys/module/acpi/parameters/ so we're going to delete the ones under /proc/ rather than fixing them.
Created attachment 10659 [details] remove ACPI debug proc interface
*** Bug 8545 has been marked as a duplicate of this bug. ***