]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
2 2.6.22 patches added
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 13 Nov 2007 20:22:01 +0000 (12:22 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 13 Nov 2007 20:22:01 +0000 (12:22 -0800)
queue-2.6.22/series [new file with mode: 0644]
queue-2.6.22/slub-fix-memory-leak-by-not-reusing-cpu_slab.patch [new file with mode: 0644]
queue-2.6.22/usb-kobil_sct-trivial-backport-to-fix-libct.patch [new file with mode: 0644]

diff --git a/queue-2.6.22/series b/queue-2.6.22/series
new file mode 100644 (file)
index 0000000..013450e
--- /dev/null
@@ -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 (file)
index 0000000..30cb1eb
--- /dev/null
@@ -0,0 +1,64 @@
+From stable-bounces@linux.kernel.org Mon Nov  5 11:24:17 2007
+From: Christoph Lameter <clameter@sgi.com>
+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 <oliver.pntr@gmail.com>, Hugh Dickins <hugh@veritas.com>, Andrew Morton <akpm@linux-foundation.org>, Linus Torvalds <torvalds@linux-foundation.org>, Willy Tarreau <w@1wt.eu>
+Message-ID: <Pine.LNX.4.64.0711051123130.15999@schroedinger.engr.sgi.com>
+
+From: Christoph Lameter <clameter@sgi.com>
+
+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 <clameter@sgi.com>
+Cc: Hugh Dickins <hugh@veritas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..2692498
--- /dev/null
@@ -0,0 +1,309 @@
+From stable-bounces@linux.kernel.org Fri Nov  9 10:45:10 2007
+From: Frank Seidel <fseidel@suse.de>
+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 <fseidel@suse.de>
+
+Backport of a patch by Alan Cox <alan@lxorguk.ukuu.org.uk> 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 <fseidel@suse.de>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ 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; i<NCCS; i++) {
+-              priv->internal_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;