From 373bbaaa5e5df4207d8ef0d31357998d092df42d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 13 Nov 2007 12:22:01 -0800 Subject: [PATCH] 2 2.6.22 patches added --- queue-2.6.22/series | 2 + ...-memory-leak-by-not-reusing-cpu_slab.patch | 64 ++++ ...il_sct-trivial-backport-to-fix-libct.patch | 309 ++++++++++++++++++ 3 files changed, 375 insertions(+) create mode 100644 queue-2.6.22/series create mode 100644 queue-2.6.22/slub-fix-memory-leak-by-not-reusing-cpu_slab.patch create mode 100644 queue-2.6.22/usb-kobil_sct-trivial-backport-to-fix-libct.patch diff --git a/queue-2.6.22/series b/queue-2.6.22/series new file mode 100644 index 00000000000..013450e7cec --- /dev/null +++ b/queue-2.6.22/series @@ -0,0 +1,2 @@ +usb-kobil_sct-trivial-backport-to-fix-libct.patch +slub-fix-memory-leak-by-not-reusing-cpu_slab.patch diff --git a/queue-2.6.22/slub-fix-memory-leak-by-not-reusing-cpu_slab.patch b/queue-2.6.22/slub-fix-memory-leak-by-not-reusing-cpu_slab.patch new file mode 100644 index 00000000000..30cb1ebaeec --- /dev/null +++ b/queue-2.6.22/slub-fix-memory-leak-by-not-reusing-cpu_slab.patch @@ -0,0 +1,64 @@ +From stable-bounces@linux.kernel.org Mon Nov 5 11:24:17 2007 +From: Christoph Lameter +Date: Mon, 5 Nov 2007 11:23:51 -0800 (PST) +Subject: SLUB: Fix memory leak by not reusing cpu_slab +To: stable@kernel.org +Cc: linux-kernel@vger.kernel.org, Olivér Pintér , Hugh Dickins , Andrew Morton , Linus Torvalds , Willy Tarreau +Message-ID: + +From: Christoph Lameter + +backport of 05aa345034de6ae9c77fb93f6a796013641d57d5 from Linus's tree. + +SLUB: Fix memory leak by not reusing cpu_slab + +Fix the memory leak that may occur when we attempt to reuse a cpu_slab +that was allocated while we reenabled interrupts in order to be able to +grow a slab cache. The per cpu freelist may contain objects and in that +situation we may overwrite the per cpu freelist pointer loosing objects. +This only occurs if we find that the concurrently allocated slab fits +our allocation needs. + +If we simply always deactivate the slab then the freelist will be properly +reintegrated and the memory leak will go away. + +Signed-off-by: Christoph Lameter +Cc: Hugh Dickins +Signed-off-by: Greg Kroah-Hartman + +--- + mm/slub.c | 22 +--------------------- + 1 file changed, 1 insertion(+), 21 deletions(-) + +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -1431,28 +1431,8 @@ new_slab: + page = new_slab(s, gfpflags, node); + if (page) { + cpu = smp_processor_id(); +- if (s->cpu_slab[cpu]) { +- /* +- * Someone else populated the cpu_slab while we +- * enabled interrupts, or we have gotten scheduled +- * on another cpu. The page may not be on the +- * requested node even if __GFP_THISNODE was +- * specified. So we need to recheck. +- */ +- if (node == -1 || +- page_to_nid(s->cpu_slab[cpu]) == node) { +- /* +- * Current cpuslab is acceptable and we +- * want the current one since its cache hot +- */ +- discard_slab(s, page); +- page = s->cpu_slab[cpu]; +- slab_lock(page); +- goto load_freelist; +- } +- /* New slab does not fit our expectations */ ++ if (s->cpu_slab[cpu]) + flush_slab(s, s->cpu_slab[cpu], cpu); +- } + slab_lock(page); + SetSlabFrozen(page); + s->cpu_slab[cpu] = page; diff --git a/queue-2.6.22/usb-kobil_sct-trivial-backport-to-fix-libct.patch b/queue-2.6.22/usb-kobil_sct-trivial-backport-to-fix-libct.patch new file mode 100644 index 00000000000..26924981074 --- /dev/null +++ b/queue-2.6.22/usb-kobil_sct-trivial-backport-to-fix-libct.patch @@ -0,0 +1,309 @@ +From stable-bounces@linux.kernel.org Fri Nov 9 10:45:10 2007 +From: Frank Seidel +Date: Fri, 9 Nov 2007 19:44:40 +0100 +Subject: USB: kobil_sct: trivial backport to fix libct +Message-ID: <200711091944.41527.fseidel@suse.de> + +From: Frank Seidel + +Backport of a patch by Alan Cox in the kernel tree +with commit 94d0f7eac77a84da2cee41b8038796891f75f09e + +Original comments: + USB: kobil_sct: Rework driver + + No hardware but this driver is currently totally broken so we can't make + it much worse. Remove all tbe broken invalid termios handling and replace + it with a proper set_termios method. + +Frank's comments: + Without this patch the userspace libct (to access the cardreader) + segfaults. + +Signed-off-by: Frank Seidel +Cc: Alan Cox +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/usb/serial/kobil_sct.c | 170 ++++++++++++++++------------------------- + 1 file changed, 69 insertions(+), 101 deletions(-) + +--- a/drivers/usb/serial/kobil_sct.c ++++ b/drivers/usb/serial/kobil_sct.c +@@ -82,6 +82,7 @@ static int kobil_tiocmset(struct usb_se + unsigned int set, unsigned int clear); + static void kobil_read_int_callback( struct urb *urb ); + static void kobil_write_callback( struct urb *purb ); ++static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old); + + + static struct usb_device_id id_table [] = { +@@ -119,6 +120,7 @@ static struct usb_serial_driver kobil_de + .attach = kobil_startup, + .shutdown = kobil_shutdown, + .ioctl = kobil_ioctl, ++ .set_termios = kobil_set_termios, + .tiocmget = kobil_tiocmget, + .tiocmset = kobil_tiocmset, + .open = kobil_open, +@@ -137,7 +139,6 @@ struct kobil_private { + int cur_pos; // index of the next char to send in buf + __u16 device_type; + int line_state; +- struct ktermios internal_termios; + }; + + +@@ -216,7 +217,7 @@ static void kobil_shutdown (struct usb_s + + static int kobil_open (struct usb_serial_port *port, struct file *filp) + { +- int i, result = 0; ++ int result = 0; + struct kobil_private *priv; + unsigned char *transfer_buffer; + int transfer_buffer_length = 8; +@@ -242,16 +243,6 @@ static int kobil_open (struct usb_serial + port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; + port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) + +- // set up internal termios structure +- priv->internal_termios.c_iflag = port->tty->termios->c_iflag; +- priv->internal_termios.c_oflag = port->tty->termios->c_oflag; +- priv->internal_termios.c_cflag = port->tty->termios->c_cflag; +- priv->internal_termios.c_lflag = port->tty->termios->c_lflag; +- +- for (i=0; iinternal_termios.c_cc[i] = port->tty->termios->c_cc[i]; +- } +- + // allocate memory for transfer buffer + transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); + if (! transfer_buffer) { +@@ -358,24 +349,26 @@ static void kobil_close (struct usb_seri + } + + +-static void kobil_read_int_callback( struct urb *purb) ++static void kobil_read_int_callback(struct urb *urb) + { + int result; +- struct usb_serial_port *port = (struct usb_serial_port *) purb->context; ++ struct usb_serial_port *port = urb->context; + struct tty_struct *tty; +- unsigned char *data = purb->transfer_buffer; ++ unsigned char *data = urb->transfer_buffer; ++ int status = urb->status; + // char *dbg_data; + + dbg("%s - port %d", __FUNCTION__, port->number); + +- if (purb->status) { +- dbg("%s - port %d Read int status not zero: %d", __FUNCTION__, port->number, purb->status); ++ if (status) { ++ dbg("%s - port %d Read int status not zero: %d", ++ __FUNCTION__, port->number, status); + return; + } +- +- tty = port->tty; +- if (purb->actual_length) { +- ++ ++ tty = port->tty; ++ if (urb->actual_length) { ++ + // BEGIN DEBUG + /* + dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); +@@ -390,15 +383,15 @@ static void kobil_read_int_callback( str + */ + // END DEBUG + +- tty_buffer_request_room(tty, purb->actual_length); +- tty_insert_flip_string(tty, data, purb->actual_length); ++ tty_buffer_request_room(tty, urb->actual_length); ++ tty_insert_flip_string(tty, data, urb->actual_length); + tty_flip_buffer_push(tty); + } + + // someone sets the dev to 0 if the close method has been called + port->interrupt_in_urb->dev = port->serial->dev; + +- result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); ++ result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); + dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result); + } + +@@ -605,102 +598,79 @@ static int kobil_tiocmset(struct usb_se + return (result < 0) ? result : 0; + } + +- +-static int kobil_ioctl(struct usb_serial_port *port, struct file *file, +- unsigned int cmd, unsigned long arg) ++static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old) + { + struct kobil_private * priv; + int result; + unsigned short urb_val = 0; +- unsigned char *transfer_buffer; +- int transfer_buffer_length = 8; +- char *settings; +- void __user *user_arg = (void __user *)arg; ++ int c_cflag = port->tty->termios->c_cflag; ++ speed_t speed; ++ void * settings; + + priv = usb_get_serial_port_data(port); +- if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { ++ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) + // This device doesn't support ioctl calls +- return 0; +- } +- +- switch (cmd) { +- case TCGETS: // 0x5401 +- if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct ktermios))) { +- dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); +- return -EFAULT; +- } +- if (kernel_termios_to_user_termios((struct ktermios __user *)arg, +- &priv->internal_termios)) +- return -EFAULT; +- return 0; +- +- case TCSETS: // 0x5402 +- if (!(port->tty->termios)) { +- dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number); +- return -ENOTTY; +- } +- if (!access_ok(VERIFY_READ, user_arg, sizeof(struct ktermios))) { +- dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); +- return -EFAULT; +- } +- if (user_termios_to_kernel_termios(&priv->internal_termios, +- (struct ktermios __user *)arg)) +- return -EFAULT; +- +- settings = kzalloc(50, GFP_KERNEL); +- if (! settings) { +- return -ENOBUFS; +- } ++ return; + +- switch (priv->internal_termios.c_cflag & CBAUD) { +- case B1200: ++ switch (speed = tty_get_baud_rate(port->tty)) { ++ case 1200: + urb_val = SUSBCR_SBR_1200; +- strcat(settings, "1200 "); + break; +- case B9600: ++ case 9600: + default: + urb_val = SUSBCR_SBR_9600; +- strcat(settings, "9600 "); + break; +- } ++ } ++ urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; + +- urb_val |= (priv->internal_termios.c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; +- strcat(settings, (priv->internal_termios.c_cflag & CSTOPB) ? "2 StopBits " : "1 StopBit "); ++ settings = kzalloc(50, GFP_KERNEL); ++ if (! settings) ++ return; + +- if (priv->internal_termios.c_cflag & PARENB) { +- if (priv->internal_termios.c_cflag & PARODD) { +- urb_val |= SUSBCR_SPASB_OddParity; +- strcat(settings, "Odd Parity"); +- } else { +- urb_val |= SUSBCR_SPASB_EvenParity; +- strcat(settings, "Even Parity"); +- } ++ sprintf(settings, "%d ", speed); ++ ++ if (c_cflag & PARENB) { ++ if (c_cflag & PARODD) { ++ urb_val |= SUSBCR_SPASB_OddParity; ++ strcat(settings, "Odd Parity"); + } else { +- urb_val |= SUSBCR_SPASB_NoParity; +- strcat(settings, "No Parity"); ++ urb_val |= SUSBCR_SPASB_EvenParity; ++ strcat(settings, "Even Parity"); + } +- dbg("%s - port %d setting port to: %s", __FUNCTION__, port->number, settings ); ++ } else { ++ urb_val |= SUSBCR_SPASB_NoParity; ++ strcat(settings, "No Parity"); ++ } + +- result = usb_control_msg( port->serial->dev, +- usb_rcvctrlpipe(port->serial->dev, 0 ), +- SUSBCRequest_SetBaudRateParityAndStopBits, +- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, +- urb_val, +- 0, +- settings, +- 0, +- KOBIL_TIMEOUT +- ); ++ result = usb_control_msg( port->serial->dev, ++ usb_rcvctrlpipe(port->serial->dev, 0 ), ++ SUSBCRequest_SetBaudRateParityAndStopBits, ++ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, ++ urb_val, ++ 0, ++ settings, ++ 0, ++ KOBIL_TIMEOUT ++ ); ++ kfree(settings); ++} + +- dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result); +- kfree(settings); ++static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) ++{ ++ struct kobil_private * priv = usb_get_serial_port_data(port); ++ unsigned char *transfer_buffer; ++ int transfer_buffer_length = 8; ++ int result; ++ ++ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) ++ // This device doesn't support ioctl calls + return 0; + ++ switch (cmd) { + case TCFLSH: // 0x540B + transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); +- if (! transfer_buffer) { ++ if (! transfer_buffer) + return -ENOBUFS; +- } + + result = usb_control_msg( port->serial->dev, + usb_rcvctrlpipe(port->serial->dev, 0 ), +@@ -714,15 +684,13 @@ static int kobil_ioctl(struct usb_seria + ); + + dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result); +- + kfree(transfer_buffer); +- return ((result < 0) ? -EFAULT : 0); +- ++ return (result < 0) ? -EFAULT : 0; ++ default: ++ return -ENOIOCTLCMD; + } +- return -ENOIOCTLCMD; + } + +- + static int __init kobil_init (void) + { + int retval; -- 2.47.3