LZ:
I tried to use spin_lock_irqsave () and found that no clock interruption was disabled. I don't know where I got it wrong?
Kernel version:
- Uname-a result:
- Linux localhost. localdomain 2.6.18 #1 sat Jul 19 13:06:00 EDT 2008 i686 i686 i386 GNU/Linux
Copy code
My code:
- # Include <Linux/kernel. h>
- # Include <Linux/init. h>
- # Include <Linux/module. h>
- # Include <Linux/spinlock. h>
- Static spinlock_t my_spinlock;
- Static int _ init init_test ()
- {
- Unsigned long flags;
- Spin_lock_init (& my_spinlock );
- Spin_lock_irqsave (& my_spinlock, flags );
- Return 0;
- }
- Static void _ exit init_exit ()
- {
- Return;
- }
- Module_init (init_test );
- Module_exit (init_exit );
Copy code
After the module is loaded, run the following command to view the Wall Clock:
- # Date; sleep 2; Date
- Output result:
- Sun Apr 19 12:59:42 EDT 2009
- Sun Apr 19 12:59:44 EDT 2009
Copy code
The clock on the wall is still changing, indicating that the clock interruption is not disabled.
But I understand that spin_lock_irqsave () will turn off all IRQ through CLI, and I do not have the spin_unlock_irqrestore () in the module, so after loading this module, the system will not respond to any external blocked interruptions. However, this is not the actual result.
Where did I get it wrong? Thank you for your advice!
Answer:
Write a section of the kernel module and userspace program to verify:
Kernel module: my_spin_lock.c
- # Include <Linux/kernel. h>
- # Include <Linux/init. h>
- # Include <Linux/module. h>
- # Include <Linux/spinlock. h>
- # Define if_mask 0x00000200
- Static spinlock_t my_spinlock;
- Static unsigned int is_interrupt_enable ()
- {
- Unsigned long my_eflags;
- ASM volatile ("pushfl/n/t"
- "Popl % 0"
- : "= A" (my_eflags ));
- Return (my_eflags & if_mask) = 0 )? 0: 1 );
- }
- Static int _ init init_test ()
- {
- Unsigned long flags;
- Spin_lock_init (& my_spinlock );
- Spin_lock_irqsave (& my_spinlock, flags );
- Printk ("from kernelspace init: interrupt was enable: % d/N", is_interrupt_enable ());
- Return 0;
- }
- Static void _ exit init_exit ()
- {
- Return;
- }
- Module_license ("GPL ");
- Module_init (init_test );
- Module_exit (init_exit );
Copy code
Generate my_spin_lock.ko after compilation
Then write a userspace program: Test. C.
- # Include <stdio. h>
- # Include <stdlib. h>
- # Define if_mask 0x00000200
- # Define pai_len 100
- Unsigned int is_interrupt_enable ()
- {
- Unsigned long my_eflags;
- ASM volatile ("pushfl/n/t"
- "Popl % 0/n/t"
- : "= A" (my_eflags ));
- Return (my_eflags & if_mask) = 0 )? 0: 1 );
- }
- Int main (INT argc, char * argv [])
- {
- If (argc! = 2)
- {
- Printf ("usersage: insmod your_kernel_module/N ");
- Return 0;
- }
- Char cmd [cmd_len];
- Memset (CMD, 0, sizeof (CMD ));
- Sprintf (CMD, "insmod % s", argv [1]);
- Printf ("from userspace, before insmod, inerrput is enable: % d/N", is_interrupt_enable ());
- System (CMD);/* insmod kernel module */
- Printf ("from userspace, after insmod, interrupt is enable: % d/N", is_interrupt_enable ());
- Memset (CMD, 0, sizeof (CMD ));
- Sprintf (CMD, "rmmod % s", argv [1]);
- System (CMD);/* rmmod kernel module */
- Return 0;
- }
Copy code
Generate the test binary file after compilation
Run the following command:
- ./Test my_spin_lock.ko
Copy code
Running result:
Quote: From userspace, before insmod, interrupt is enable: 1
From kernelspace init: interrupt was enable: 0
From userspace, after insmod, interrupt is enable: 1
It can be seen that interrupt is indeed disabled after the init function of the kernel module is run. Then return to the user State. Interrupt is enabled.