isicom: Fix buffer allocation
PATCH 1/1 isicom: Fix buffer allocation
Fix the rather strange buffer management on open that turned up while auditing for BKL dependancies
drivers/char/isicom.c +6 -8
@@ -813,15 +813,13 @@return 0 ;if (!port->xmit_buf) {/* Relies on BKL */ -void *xmit_buf = (void *)get_zeroed_page (GFP_KERNEL ); - -if (xmit_buf ==NULL ) +unsigned long page =get_zeroed_page (GFP_KERNEL ); +if (page ==0 )return -ENOMEM ; -if (port->xmit_buf) { -free_page ((unsigned long )xmit_buf); -return -ERESTARTSYS ; - } - port->xmit_buf = xmit_buf; +if (port->xmit_buf) +free_page (page); +else + port->xmit_buf = (unsigned char *) page; }spin_lock_irqsave (&card->card_lock, flags);
Quoted 10 lines · Alan Cox
Fix the rather strange buffer management on open that turned up while auditing for BKL dependancies
Signed-off-by Alan Cox <[email protected]>diff -u --new-file --recursive --exclude-from
/usr/src/excludelinux.vanilla-2.6.25-mm1/drivers/char/isicom.clinux-2.6.25-mm1/drivers/char/isicom.cdrivers/char/isicom.c +0
-0@@ -813,15 +813,13 @@return 0 ;
drivers/char/isicom.c line 823
Quoted 10 lines
drivers/char/isicom.c +6
-0if (!port->xmit_buf) {/* Relies on BKL */ +unsigned long page =get_zeroed_page (GFP_KERNEL ); +if (page ==0 )return -ENOMEM ; +if (port->xmit_buf) +free_page (page); +else + port->xmit_buf = (unsigned char *) page; }
Still looks rather strange. An if(x) inside an if(!x) ?
OG.
Quoted 7 lines · Olivier Galibert
Quoted 7 lines
drivers/char/isicom.c +2
-0@@ -813,15 +813,13 @@return 0 ;if (!port->xmit_buf) {/* Relies on BKL */ +unsigned long page =get_zeroed_page (GFP_KERNEL ); +if (page ==0 )return -ENOMEM ;
Quoted 8 lines
drivers/char/isicom.c line 823
Quoted 5 lines
drivers/char/isicom.c +4
-0+if (port->xmit_buf) +free_page (page); +else + port->xmit_buf = (unsigned char *) page; }Still looks rather strange. An if(x) inside an if(!x) ?
The joys of parallelism. The serial drivers mostly do this because they are using the BKL for open/close paths being a bit prehistoric (its on the hit list ;))
CPU #1
open port->xmit_buf == NULL get_zeroed_page [Can sleep dropping BKL]
CPU #2
get_zeroed_page port->xmit_buf == NULL port->xmit_buf = page
CPU #1
port->xmit_buf != NULL free page
A fine example of why proper locking is good ;)