]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.37 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 15 Feb 2011 13:54:27 +0000 (05:54 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 15 Feb 2011 13:54:27 +0000 (05:54 -0800)
queue-2.6.37/af_unix-avoid-socket-sk-null-oops-in-stream-connect-security-hooks.patch [new file with mode: 0644]
queue-2.6.37/atyfb-fix-bootup-hangs-on-sparc64.patch [new file with mode: 0644]
queue-2.6.37/inet6-prevent-network-storms-caused-by-linux-ipv6-routers.patch [new file with mode: 0644]
queue-2.6.37/ipv4-ip-defragmentation-must-be-ecn-aware.patch [new file with mode: 0644]
queue-2.6.37/net-add-pollpri-to-sock_def_readable.patch [new file with mode: 0644]
queue-2.6.37/net_sched-pfifo_head_drop-problem.patch [new file with mode: 0644]
queue-2.6.37/rapidio-fix-hang-on-rapidio-doorbell-queue-full-condition.patch [new file with mode: 0644]
queue-2.6.37/series

diff --git a/queue-2.6.37/af_unix-avoid-socket-sk-null-oops-in-stream-connect-security-hooks.patch b/queue-2.6.37/af_unix-avoid-socket-sk-null-oops-in-stream-connect-security-hooks.patch
new file mode 100644 (file)
index 0000000..ff4cadc
--- /dev/null
@@ -0,0 +1,170 @@
+From 0a45581901aa642be8a4a1af6acada3dd2696fb8 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 5 Jan 2011 15:38:53 -0800
+Subject: af_unix: Avoid socket->sk NULL OOPS in stream connect security hooks.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 3610cda53f247e176bcbb7a7cca64bc53b12acdb ]
+
+unix_release() can asynchornously set socket->sk to NULL, and
+it does so without holding the unix_state_lock() on "other"
+during stream connects.
+
+However, the reverse mapping, sk->sk_socket, is only transitioned
+to NULL under the unix_state_lock().
+
+Therefore make the security hooks follow the reverse mapping instead
+of the forward mapping.
+
+Reported-by: Jeremy Fitzhardinge <jeremy@goop.org>
+Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ include/linux/security.h   |   15 +++++++--------
+ net/unix/af_unix.c         |    2 +-
+ security/capability.c      |    2 +-
+ security/security.c        |    3 +--
+ security/selinux/hooks.c   |   10 +++++-----
+ security/smack/smack_lsm.c |   14 +++++++-------
+ 6 files changed, 22 insertions(+), 24 deletions(-)
+
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -796,8 +796,9 @@ static inline void security_free_mnt_opt
+  * @unix_stream_connect:
+  *    Check permissions before establishing a Unix domain stream connection
+  *    between @sock and @other.
+- *    @sock contains the socket structure.
+- *    @other contains the peer socket structure.
++ *    @sock contains the sock structure.
++ *    @other contains the peer sock structure.
++ *    @newsk contains the new sock structure.
+  *    Return 0 if permission is granted.
+  * @unix_may_send:
+  *    Check permissions before connecting or sending datagrams from @sock to
+@@ -1568,8 +1569,7 @@ struct security_operations {
+       int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
+ #ifdef CONFIG_SECURITY_NETWORK
+-      int (*unix_stream_connect) (struct socket *sock,
+-                                  struct socket *other, struct sock *newsk);
++      int (*unix_stream_connect) (struct sock *sock, struct sock *other, struct sock *newsk);
+       int (*unix_may_send) (struct socket *sock, struct socket *other);
+       int (*socket_create) (int family, int type, int protocol, int kern);
+@@ -2525,8 +2525,7 @@ static inline int security_inode_getsecc
+ #ifdef CONFIG_SECURITY_NETWORK
+-int security_unix_stream_connect(struct socket *sock, struct socket *other,
+-                               struct sock *newsk);
++int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk);
+ int security_unix_may_send(struct socket *sock,  struct socket *other);
+ int security_socket_create(int family, int type, int protocol, int kern);
+ int security_socket_post_create(struct socket *sock, int family,
+@@ -2567,8 +2566,8 @@ void security_tun_dev_post_create(struct
+ int security_tun_dev_attach(struct sock *sk);
+ #else /* CONFIG_SECURITY_NETWORK */
+-static inline int security_unix_stream_connect(struct socket *sock,
+-                                             struct socket *other,
++static inline int security_unix_stream_connect(struct sock *sock,
++                                             struct sock *other,
+                                              struct sock *newsk)
+ {
+       return 0;
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1156,7 +1156,7 @@ restart:
+               goto restart;
+       }
+-      err = security_unix_stream_connect(sock, other->sk_socket, newsk);
++      err = security_unix_stream_connect(sk, other, newsk);
+       if (err) {
+               unix_state_unlock(sk);
+               goto out_unlock;
+--- a/security/capability.c
++++ b/security/capability.c
+@@ -548,7 +548,7 @@ static int cap_sem_semop(struct sem_arra
+ }
+ #ifdef CONFIG_SECURITY_NETWORK
+-static int cap_unix_stream_connect(struct socket *sock, struct socket *other,
++static int cap_unix_stream_connect(struct sock *sock, struct sock *other,
+                                  struct sock *newsk)
+ {
+       return 0;
+--- a/security/security.c
++++ b/security/security.c
+@@ -977,8 +977,7 @@ EXPORT_SYMBOL(security_inode_getsecctx);
+ #ifdef CONFIG_SECURITY_NETWORK
+-int security_unix_stream_connect(struct socket *sock, struct socket *other,
+-                               struct sock *newsk)
++int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk)
+ {
+       return security_ops->unix_stream_connect(sock, other, newsk);
+ }
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -3921,18 +3921,18 @@ static int selinux_socket_shutdown(struc
+       return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN);
+ }
+-static int selinux_socket_unix_stream_connect(struct socket *sock,
+-                                            struct socket *other,
++static int selinux_socket_unix_stream_connect(struct sock *sock,
++                                            struct sock *other,
+                                             struct sock *newsk)
+ {
+-      struct sk_security_struct *sksec_sock = sock->sk->sk_security;
+-      struct sk_security_struct *sksec_other = other->sk->sk_security;
++      struct sk_security_struct *sksec_sock = sock->sk_security;
++      struct sk_security_struct *sksec_other = other->sk_security;
+       struct sk_security_struct *sksec_new = newsk->sk_security;
+       struct common_audit_data ad;
+       int err;
+       COMMON_AUDIT_DATA_INIT(&ad, NET);
+-      ad.u.net.sk = other->sk;
++      ad.u.net.sk = other;
+       err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
+                          sksec_other->sclass,
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -2408,22 +2408,22 @@ static int smack_setprocattr(struct task
+ /**
+  * smack_unix_stream_connect - Smack access on UDS
+- * @sock: one socket
+- * @other: the other socket
++ * @sock: one sock
++ * @other: the other sock
+  * @newsk: unused
+  *
+  * Return 0 if a subject with the smack of sock could access
+  * an object with the smack of other, otherwise an error code
+  */
+-static int smack_unix_stream_connect(struct socket *sock,
+-                                   struct socket *other, struct sock *newsk)
++static int smack_unix_stream_connect(struct sock *sock,
++                                   struct sock *other, struct sock *newsk)
+ {
+-      struct inode *sp = SOCK_INODE(sock);
+-      struct inode *op = SOCK_INODE(other);
++      struct inode *sp = SOCK_INODE(sock->sk_socket);
++      struct inode *op = SOCK_INODE(other->sk_socket);
+       struct smk_audit_info ad;
+       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
+-      smk_ad_setfield_u_net_sk(&ad, other->sk);
++      smk_ad_setfield_u_net_sk(&ad, other);
+       return smk_access(smk_of_inode(sp), smk_of_inode(op),
+                                MAY_READWRITE, &ad);
+ }
diff --git a/queue-2.6.37/atyfb-fix-bootup-hangs-on-sparc64.patch b/queue-2.6.37/atyfb-fix-bootup-hangs-on-sparc64.patch
new file mode 100644 (file)
index 0000000..ef69384
--- /dev/null
@@ -0,0 +1,93 @@
+From 09798eb9479da3413bdf96e7d22a84d8b21e05e1 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 5 Jan 2011 13:08:06 -0800
+Subject: atyfb: Fix bootup hangs on sparc64.
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 09798eb9479da3413bdf96e7d22a84d8b21e05e1 ]
+
+After commit 25edd6946a1d74e5e77813c2324a0908c68bcf9e ("sparc64: Get
+rid of indirect p1275 PROM call buffer.")  we can't pass virtual
+addresses >4GB to PROM calls.
+
+Largely this is never necessary in drivers because we have a copy of
+the entire PROM device tree in the kernel and a set of of_*()
+interfaces to access it.
+
+Unfortunately there were some lingering prom calls in the atyfb
+driver, in particular prom_finddevice() was being called with an
+on-stack address which could be anywhere.
+
+This code is actually probing for information we already have, the
+PROM choosen console output device is stored in of_console_device so
+all of this nasty code consolidates into a one-line comparison.
+
+Next we have some prom_getintdefault() calls which are trivially
+transformed into the equivalent of_getintprop_default().
+
+Special thanks to Fabio, who figured out exactly where the bootup
+was hanging.  That made this bug trivial to fix.
+
+Reported-by: Fabio M. Di NItto <fabbione@fabbione.net>
+Reported-by: Sam Ravnborg <sam@ravnborg.org>
+Reported-by: Frans van Berckel <fberckel@xs4all.nl>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Fabio M. Di NItto <fabbione@fabbione.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/video/aty/atyfb_base.c |   27 +++++----------------------
+ 1 file changed, 5 insertions(+), 22 deletions(-)
+
+--- a/drivers/video/aty/atyfb_base.c
++++ b/drivers/video/aty/atyfb_base.c
+@@ -2969,10 +2969,8 @@ static int __devinit atyfb_setup_sparc(s
+ {
+       struct atyfb_par *par = info->par;
+       struct device_node *dp;
+-      char prop[128];
+-      phandle node;
+-      int len, i, j, ret;
+       u32 mem, chip_id;
++      int i, j, ret;
+       /*
+        * Map memory-mapped registers.
+@@ -3088,23 +3086,8 @@ static int __devinit atyfb_setup_sparc(s
+               aty_st_le32(MEM_CNTL, mem, par);
+       }
+-      /*
+-       * If this is the console device, we will set default video
+-       * settings to what the PROM left us with.
+-       */
+-      node = prom_getchild(prom_root_node);
+-      node = prom_searchsiblings(node, "aliases");
+-      if (node) {
+-              len = prom_getproperty(node, "screen", prop, sizeof(prop));
+-              if (len > 0) {
+-                      prop[len] = '\0';
+-                      node = prom_finddevice(prop);
+-              } else
+-                      node = 0;
+-      }
+-
+       dp = pci_device_to_OF_node(pdev);
+-      if (node == dp->phandle) {
++      if (dp == of_console_device) {
+               struct fb_var_screeninfo *var = &default_var;
+               unsigned int N, P, Q, M, T, R;
+               u32 v_total, h_total;
+@@ -3112,9 +3095,9 @@ static int __devinit atyfb_setup_sparc(s
+               u8 pll_regs[16];
+               u8 clock_cntl;
+-              crtc.vxres = prom_getintdefault(node, "width", 1024);
+-              crtc.vyres = prom_getintdefault(node, "height", 768);
+-              var->bits_per_pixel = prom_getintdefault(node, "depth", 8);
++              crtc.vxres = of_getintprop_default(dp, "width", 1024);
++              crtc.vyres = of_getintprop_default(dp, "height", 768);
++              var->bits_per_pixel = of_getintprop_default(dp, "depth", 8);
+               var->xoffset = var->yoffset = 0;
+               crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
+               crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
diff --git a/queue-2.6.37/inet6-prevent-network-storms-caused-by-linux-ipv6-routers.patch b/queue-2.6.37/inet6-prevent-network-storms-caused-by-linux-ipv6-routers.patch
new file mode 100644 (file)
index 0000000..83da8ac
--- /dev/null
@@ -0,0 +1,35 @@
+From dc36df3b8b791ad6d668df5fe5533cb9776ac88a Mon Sep 17 00:00:00 2001
+From: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Date: Wed, 12 Jan 2011 08:34:08 +0000
+Subject: inet6: prevent network storms caused by linux IPv6 routers
+
+
+From: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+
+[ Upstream commit 72b43d0898e97f588293b4a24b33c58c46633d81 ]
+
+Linux IPv6 forwards unicast packets, which are link layer multicasts...
+The hole was present since day one. I was 100% this check is there, but it is not.
+
+The problem shows itself, f.e. when Microsoft Network Load Balancer runs on a network.
+This software resolves IPv6 unicast addresses to multicast MAC addresses.
+
+Signed-off-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/ipv6/ip6_output.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -401,6 +401,9 @@ int ip6_forward(struct sk_buff *skb)
+               goto drop;
+       }
++      if (skb->pkt_type != PACKET_HOST)
++              goto drop;
++
+       skb_forward_csum(skb);
+       /*
diff --git a/queue-2.6.37/ipv4-ip-defragmentation-must-be-ecn-aware.patch b/queue-2.6.37/ipv4-ip-defragmentation-must-be-ecn-aware.patch
new file mode 100644 (file)
index 0000000..8bfb959
--- /dev/null
@@ -0,0 +1,140 @@
+From b3fe7bc4469f681a6b2454324120bb58a01ae5b9 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Wed, 5 Jan 2011 07:52:55 +0000
+Subject: ipv4: IP defragmentation must be ECN aware
+
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+[ Upstream commit 6623e3b24a5ebb07e81648c478d286a1329ab891 ]
+
+RFC3168 (The Addition of Explicit Congestion Notification to IP)
+states :
+
+5.3.  Fragmentation
+
+   ECN-capable packets MAY have the DF (Don't Fragment) bit set.
+   Reassembly of a fragmented packet MUST NOT lose indications of
+   congestion.  In other words, if any fragment of an IP packet to be
+   reassembled has the CE codepoint set, then one of two actions MUST be
+   taken:
+
+      * Set the CE codepoint on the reassembled packet.  However, this
+        MUST NOT occur if any of the other fragments contributing to
+        this reassembly carries the Not-ECT codepoint.
+
+      * The packet is dropped, instead of being reassembled, for any
+        other reason.
+
+This patch implements this requirement for IPv4, choosing the first
+action :
+
+If one fragment had NO-ECT codepoint
+        reassembled frame has NO-ECT
+ElIf one fragment had CE codepoint
+        reassembled frame has CE
+
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/ipv4/ip_fragment.c |   34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+--- a/net/ipv4/ip_fragment.c
++++ b/net/ipv4/ip_fragment.c
+@@ -45,6 +45,7 @@
+ #include <linux/udp.h>
+ #include <linux/inet.h>
+ #include <linux/netfilter_ipv4.h>
++#include <net/inet_ecn.h>
+ /* NOTE. Logic of IP defragmentation is parallel to corresponding IPv6
+  * code now. If you change something here, _PLEASE_ update ipv6/reassembly.c
+@@ -70,11 +71,28 @@ struct ipq {
+       __be32          daddr;
+       __be16          id;
+       u8              protocol;
++      u8              ecn; /* RFC3168 support */
+       int             iif;
+       unsigned int    rid;
+       struct inet_peer *peer;
+ };
++#define IPFRAG_ECN_CLEAR  0x01 /* one frag had INET_ECN_NOT_ECT */
++#define IPFRAG_ECN_SET_CE 0x04 /* one frag had INET_ECN_CE */
++
++static inline u8 ip4_frag_ecn(u8 tos)
++{
++      tos = (tos & INET_ECN_MASK) + 1;
++      /*
++       * After the last operation we have (in binary):
++       * INET_ECN_NOT_ECT => 001
++       * INET_ECN_ECT_1   => 010
++       * INET_ECN_ECT_0   => 011
++       * INET_ECN_CE      => 100
++       */
++      return (tos & 2) ? 0 : tos;
++}
++
+ static struct inet_frags ip4_frags;
+ int ip_frag_nqueues(struct net *net)
+@@ -137,6 +155,7 @@ static void ip4_frag_init(struct inet_fr
+       qp->protocol = arg->iph->protocol;
+       qp->id = arg->iph->id;
++      qp->ecn = ip4_frag_ecn(arg->iph->tos);
+       qp->saddr = arg->iph->saddr;
+       qp->daddr = arg->iph->daddr;
+       qp->user = arg->user;
+@@ -316,6 +335,7 @@ static int ip_frag_reinit(struct ipq *qp
+       qp->q.fragments = NULL;
+       qp->q.fragments_tail = NULL;
+       qp->iif = 0;
++      qp->ecn = 0;
+       return 0;
+ }
+@@ -328,6 +348,7 @@ static int ip_frag_queue(struct ipq *qp,
+       int flags, offset;
+       int ihl, end;
+       int err = -ENOENT;
++      u8 ecn;
+       if (qp->q.last_in & INET_FRAG_COMPLETE)
+               goto err;
+@@ -339,6 +360,7 @@ static int ip_frag_queue(struct ipq *qp,
+               goto err;
+       }
++      ecn = ip4_frag_ecn(ip_hdr(skb)->tos);
+       offset = ntohs(ip_hdr(skb)->frag_off);
+       flags = offset & ~IP_OFFSET;
+       offset &= IP_OFFSET;
+@@ -472,6 +494,7 @@ found:
+       }
+       qp->q.stamp = skb->tstamp;
+       qp->q.meat += skb->len;
++      qp->ecn |= ecn;
+       atomic_add(skb->truesize, &qp->q.net->mem);
+       if (offset == 0)
+               qp->q.last_in |= INET_FRAG_FIRST_IN;
+@@ -583,6 +606,17 @@ static int ip_frag_reasm(struct ipq *qp,
+       iph = ip_hdr(head);
+       iph->frag_off = 0;
+       iph->tot_len = htons(len);
++      /* RFC3168 5.3 Fragmentation support
++       * If one fragment had INET_ECN_NOT_ECT,
++       *      reassembled frame also has INET_ECN_NOT_ECT
++       * Elif one fragment had INET_ECN_CE
++       *      reassembled frame also has INET_ECN_CE
++       */
++      if (qp->ecn & IPFRAG_ECN_CLEAR)
++              iph->tos &= ~INET_ECN_MASK;
++      else if (qp->ecn & IPFRAG_ECN_SET_CE)
++              iph->tos |= INET_ECN_CE;
++
+       IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
+       qp->q.fragments = NULL;
+       qp->q.fragments_tail = NULL;
diff --git a/queue-2.6.37/net-add-pollpri-to-sock_def_readable.patch b/queue-2.6.37/net-add-pollpri-to-sock_def_readable.patch
new file mode 100644 (file)
index 0000000..52534cf
--- /dev/null
@@ -0,0 +1,49 @@
+From 4429b20f7c404b6e9b1926931eb3065e346c12fc Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Thu, 6 Jan 2011 10:54:29 -0800
+Subject: net: add POLLPRI to sock_def_readable()
+
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+[ Upstream commit 2c6607c611cb7bf0a6750bcea34a258144e302c5 ]
+
+Leonardo Chiquitto found poll() could block forever on tcp sockets and
+Urgent data was received, if the event flag only contains POLLPRI.
+
+He did a bisection and found commit 4938d7e0233 (poll: avoid extra
+wakeups in select/poll) was the source of the problem.
+
+Problem is TCP sockets use standard sock_def_readable() function for
+their sk_data_ready() handler, and sock_def_readable() doesnt signal
+POLLPRI.
+
+Only TCP is affected by the problem. Adding POLLPRI to the list of flags
+might trigger unnecessary schedules, but URGENT handling is such a
+seldom used feature this seems a good compromise.
+
+Thanks a lot to Leonardo for providing the bisection result and a test
+program as well.
+
+Reference : http://www.spinics.net/lists/netdev/msg151793.html
+
+Reported-and-bisected-by: Leonardo Chiquitto <leonardo.lists@gmail.com>
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Tested-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/core/sock.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1907,7 +1907,7 @@ static void sock_def_readable(struct soc
+       rcu_read_lock();
+       wq = rcu_dereference(sk->sk_wq);
+       if (wq_has_sleeper(wq))
+-              wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
++              wake_up_interruptible_sync_poll(&wq->wait, POLLIN | POLLPRI |
+                                               POLLRDNORM | POLLRDBAND);
+       sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
+       rcu_read_unlock();
diff --git a/queue-2.6.37/net_sched-pfifo_head_drop-problem.patch b/queue-2.6.37/net_sched-pfifo_head_drop-problem.patch
new file mode 100644 (file)
index 0000000..fde663f
--- /dev/null
@@ -0,0 +1,50 @@
+From c31d192b403aa8944c24133eea7db6de4541d24f Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Wed, 5 Jan 2011 10:35:02 +0000
+Subject: net_sched: pfifo_head_drop problem
+
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+[ Upstream commit 44b8288308ac9da27eab7d7bdbf1375a568805c3 ]
+
+commit 57dbb2d83d100ea (sched: add head drop fifo queue)
+introduced pfifo_head_drop, and broke the invariant that
+sch->bstats.bytes and sch->bstats.packets are COUNTER (increasing
+counters only)
+
+This can break estimators because est_timer() handles unsigned deltas
+only. A decreasing counter can then give a huge unsigned delta.
+
+My mid term suggestion would be to change things so that
+sch->bstats.bytes and sch->bstats.packets are incremented in dequeue()
+only, not at enqueue() time. We also could add drop_bytes/drop_packets
+and provide estimations of drop rates.
+
+It would be more sensible anyway for very low speeds, and big bursts.
+Right now, if we drop packets, they still are accounted in byte/packets
+abolute counters and rate estimators.
+
+Before this mid term change, this patch makes pfifo_head_drop behavior
+similar to other qdiscs in case of drops :
+Dont decrement sch->bstats.bytes and sch->bstats.packets
+
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Acked-by: Hagen Paul Pfeifer <hagen@jauu.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/sched/sch_fifo.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/net/sched/sch_fifo.c
++++ b/net/sched/sch_fifo.c
+@@ -54,8 +54,6 @@ static int pfifo_tail_enqueue(struct sk_
+       /* queue full, remove one skb to fulfill the limit */
+       skb_head = qdisc_dequeue_head(sch);
+-      sch->bstats.bytes -= qdisc_pkt_len(skb_head);
+-      sch->bstats.packets--;
+       sch->qstats.drops++;
+       kfree_skb(skb_head);
diff --git a/queue-2.6.37/rapidio-fix-hang-on-rapidio-doorbell-queue-full-condition.patch b/queue-2.6.37/rapidio-fix-hang-on-rapidio-doorbell-queue-full-condition.patch
new file mode 100644 (file)
index 0000000..76a998e
--- /dev/null
@@ -0,0 +1,44 @@
+From 12a4dc43911785f51a596f771ae0701b18d436f1 Mon Sep 17 00:00:00 2001
+From: Thomas Taranowski <tom@baringforge.com>
+Date: Wed, 12 Jan 2011 17:00:44 -0800
+Subject: rapidio: fix hang on RapidIO doorbell queue full condition
+
+From: Thomas Taranowski <tom@baringforge.com>
+
+commit 12a4dc43911785f51a596f771ae0701b18d436f1 upstream.
+
+In fsl_rio_dbell_handler() the code currently simply acknowledges the QFI
+queue full interrupt, but does nothing to resolve the queue full
+condition.  Instead, it jumps to the end of the isr.  When a queue full
+condition occurs, the isr is then re-entered immediately and continually,
+forever.
+
+The fix is to just fall through and read out current doorbell entries.
+
+Signed-off-by: Thomas Taranowski <tom@baringforge.com>
+Cc: Alexandre Bounine <alexandre.bounine@idt.com>
+Cc: Kumar Gala <galak@kernel.crashing.org>
+Cc: Matt Porter <mporter@kernel.crashing.org>
+Cc: Li Yang <leoli@freescale.com>
+Cc: Thomas Moll <thomas.moll@sysgo.com>
+Cc: Micha Nelissen <micha@neli.hopto.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Grant Likely <grant.likely@secretlab.ca>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/sysdev/fsl_rio.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/arch/powerpc/sysdev/fsl_rio.c
++++ b/arch/powerpc/sysdev/fsl_rio.c
+@@ -973,7 +973,6 @@ fsl_rio_dbell_handler(int irq, void *dev
+       if (dsr & DOORBELL_DSR_QFI) {
+               pr_info("RIO: doorbell queue full\n");
+               out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI);
+-              goto out;
+       }
+       /* XXX Need to check/dispatch until queue empty */
index fbb536b7fbd3a2e4993fc370ce7837e0d17fd282..0b4e601588c9d72b3129e89f3abb2e6988b231ff 100644 (file)
@@ -133,3 +133,10 @@ ext4-fix-panic-on-module-unload-when-stopping-lazyinit-thread.patch
 ext4-unregister-features-interface-on-module-unload.patch
 ext4-fix-data-corruption-with-multi-block-writepages-support.patch
 ext4-make-grpinfo-slab-cache-names-static.patch
+rapidio-fix-hang-on-rapidio-doorbell-queue-full-condition.patch
+atyfb-fix-bootup-hangs-on-sparc64.patch
+af_unix-avoid-socket-sk-null-oops-in-stream-connect-security-hooks.patch
+inet6-prevent-network-storms-caused-by-linux-ipv6-routers.patch
+net-add-pollpri-to-sock_def_readable.patch
+ipv4-ip-defragmentation-must-be-ecn-aware.patch
+net_sched-pfifo_head_drop-problem.patch