Hi all,
I have a question concerning the declaration of a wait queue in a device
driver.
I've declared a srtucture in my header file. This structure is used for
building a circular linked list and, amongst other, holds a wait queue.
I've dynamically allocated memory for the linked list by using kmalloc
for each list entry (in the read section of the driver) so every
instance of the read process can go to sleep on its own wait struct in
the list.
This however doesn't seem to work. When the read process wakes up from
the wait queue, I get an oops message (oops.txt in attachment). When I
have the read processes sleep on a statically declared wait structure,
it works fine. So I know _what_ I'm doing wrong but I don't understand
_why_ it is wrong. Printk-ing the *wq pointer on console works fine and
shows 756e696c. The oops message complains about a page fault at virtual
address 756e6970, 4 bytes higher. Accessing other structure members goes
fine.
Could someone please explain?
The assembly in the oops message shows "movl 0x4(%ecx),%eax" which
accounts for the 4 bytes difference between the pointer and the page
faulted virtual memory address. I don't have a clue about what I'm
trying to say here, but if somebody knows links to any information about
making sense of oops messages, I appreciate that.
Here's the relevant code:
In header.h:
typedef struct list_entry * ptr_to_list_entry;
struct list_entry {
unsigned long data;
struct wait_queue *wq;
ptr_to_list_entry next;
In read.cQuote:};
ssize_t read(struct file *file, char *buffer, size_t length, loff_t
*offset)
{
ptr_to_list_entry new_entry;
new_entry=(ptr_to_list_entry)kmalloc(sizeof(struct
list_entry),GFP_KERNEL);
/* I assume sizeof(struct list_entry) doesn't result in what I hoped
for */
/* Some code to set up the linked list */
printk(KERN_ERR "new_entry->wq is: %p\n", new_entry->wq);
interruptible_sleep_on(&new_entry->wq);
/* rest of code */
Quote:}
[
oops.txt 2K ]
WARNING: This version of ksymoops is obsolete.
WARNING: The current version can be obtained from ftp://ftp.ocs.com.au/pub/ksymoops
Options used: -V (default)
-o /lib/modules/2.2.12-20/ (default)
-k /proc/ksyms (default)
-l /proc/modules (default)
-m /boot/System.map (specified)
-c 1 (default)
Unable to handle kernel paging request at virtual address 756e6970
current->tss.cr3 = 00c88000, %cr3 = 00c88000
*pde = 00000000
Oops: 0000
CPU: 0
EIP: 0010:[interruptible_sleep_on+60/92]
EFLAGS: 00010046
eax: 00c88000 ebx: c037bf4c ecx: 756e696c edx: 756e696c
esi: 00000286 edi: c037bf98 ebp: c037bf54 esp: c037bf4c
ds: 0018 es: 0018 ss: 0018
Process rtr_read (pid: 280, process nr: 20, stackpage=c037b000)
Stack: c037a000 756e696c c037bf98 c2809de5 c280aa13 756e696c c12f9f80 ffffffea
00000000 c0531da0 c0125fcb 000b1210 00000001 00000000 00000005 00000000
00000000 00000000 00000000 00000008 c01255b2 c12f9f80 08049654 00000008
Call Trace: [<c2809de5>] [<c280aa13>] [chrdev_open+63/76] [sys_read+174/196] [system_call+52/56]
Code: 8b 41 04 39 d8 74 0a 90 89 c2 8b 42 04 39 d8 75 f7 89 4a 04
Trace: c2809de5 <fat_search_long+dd/5d0>
Trace: c280aa13 <vfat_ioctl_fill+7/174>
Code: 00000000 Before first symbol 00000000 <_IP>: <===
Code: 00000000 Before first symbol 0: 8b 41 04 movl 0x4(%ecx),%eax <===
Code: 00000003 Before first symbol 3: 39 d8 cmpl %ebx,%eax
Code: 00000005 Before first symbol 5: 74 0a je 00000011 Before first symbol
Code: 00000007 Before first symbol 7: 90 nop
Code: 00000008 Before first symbol 8: 89 c2 movl %eax,%edx
Code: 0000000a Before first symbol a: 8b 42 04 movl 0x4(%edx),%eax
Code: 0000000d Before first symbol d: 39 d8 cmpl %ebx,%eax
Code: 0000000f Before first symbol f: 75 f7 jne 00000008 Before first symbol
Code: 00000011 Before first symbol 11: 89 4a 04 movl %ecx,0x4(%edx)
3 warnings issued. Results may not be reliable.