Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ip2: avoid add_timer with pending timer

add_timer() is not supposed to be called when the timer is pending.
ip2 driver attempts to avoid that condition by setting and resetting
a flag (TimerOn) in timer function. But there is some gap between
add_timer() and setting TimerOn.

This patch fix this problem by using mod_timer() and remove TimerOn
which has been unnecessary by this change.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Akinobu Mita and committed by
Linus Torvalds
9d020a2e f1ddfd95

+4 -15
+4 -15
drivers/char/ip2/ip2main.c
··· 249 249 */ 250 250 #define POLL_TIMEOUT (jiffies + 1) 251 251 static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); 252 - static char TimerOn; 253 252 254 253 #ifdef IP2DEBUG_TRACE 255 254 /* Trace (debug) buffer data */ ··· 373 374 int err; 374 375 int i; 375 376 376 - /* Stop poll timer if we had one. */ 377 - if (TimerOn) { 378 - del_timer(&PollTimer); 379 - TimerOn = 0; 380 - } 377 + del_timer_sync(&PollTimer); 381 378 382 379 /* Reset the boards we have. */ 383 380 for (i = 0; i < IP2_MAX_BOARDS; i++) ··· 769 774 } 770 775 if (ip2config.irq[i] == CIR_POLL) { 771 776 retry: 772 - if (!TimerOn) { 773 - PollTimer.expires = POLL_TIMEOUT; 774 - add_timer(&PollTimer); 775 - TimerOn = 1; 777 + if (!timer_pending(&PollTimer)) { 778 + mod_timer(&PollTimer, POLL_TIMEOUT); 776 779 printk(KERN_INFO "IP2: polling\n"); 777 780 } 778 781 } else { ··· 1276 1283 { 1277 1284 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); 1278 1285 1279 - TimerOn = 0; // it's the truth but not checked in service 1280 - 1281 1286 // Just polled boards, IRQ = 0 will hit all non-interrupt boards. 1282 1287 // It will NOT poll boards handled by hard interrupts. 1283 1288 // The issue of queued BH interrupts is handled in ip2_interrupt(). 1284 1289 ip2_polled_interrupt(); 1285 1290 1286 - PollTimer.expires = POLL_TIMEOUT; 1287 - add_timer( &PollTimer ); 1288 - TimerOn = 1; 1291 + mod_timer(&PollTimer, POLL_TIMEOUT); 1289 1292 1290 1293 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); 1291 1294 }