Skip to contentSkip to conversation

isicom: Fix buffer allocation

PATCH In review Alan Cox 3 participants 3 messages Apr 29, 2008 Char and misc drivers

lore
Share & tools
lore

Alan Cox

author
#0 lore raw

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
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.25-mm1/drivers/char/isicom.c linux-2.6.25-mm1/drivers/char/isicom.c
@@ -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);
#1 lore raw
Quoted 10 lines · Alan Cox

Fix the rather strange buffer management on open that turned up while auditing for BKL dependancies

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.25-mm1/drivers/char/isicom.c linux-2.6.25-mm1/drivers/char/isicom.c

drivers/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 -0
 	if (!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.

#2 lore raw
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 ;)