From 4a06153ba7620d7384db01512cb950621a8c430d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 7 Apr 2012 02:43:08 +0000 Subject: [PATCH] [x86] ioat: fix size of completion for Xen (Closes: #660554) svn path=/dists/sid/linux-2.6/; revision=18911 --- debian/changelog | 10 + .../all/net-fix-proc-net-dev-regression.patch | 183 ++++++++++++++++++ debian/patches/series/base | 2 + 3 files changed, 195 insertions(+) create mode 100644 debian/patches/bugfix/all/net-fix-proc-net-dev-regression.patch diff --git a/debian/changelog b/debian/changelog index ed59a0d01..8bc251ee6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +linux-2.6 (3.2.14-2) UNRELEASED; urgency=low + + [ Ben Hutchings ] + * net: fix /proc/net/dev regression (Closes: #659499) + + [ Jonathan Nieder ] + * [x86] ioat: fix size of 'completion' for Xen (Closes: #660554) + + -- Ben Hutchings Sat, 07 Apr 2012 01:56:13 +0100 + linux-2.6 (3.2.14-1) unstable; urgency=low * New upstream stable update: diff --git a/debian/patches/bugfix/all/net-fix-proc-net-dev-regression.patch b/debian/patches/bugfix/all/net-fix-proc-net-dev-regression.patch new file mode 100644 index 000000000..2bc8b2ead --- /dev/null +++ b/debian/patches/bugfix/all/net-fix-proc-net-dev-regression.patch @@ -0,0 +1,183 @@ +From: Eric Dumazet +Date: Mon, 2 Apr 2012 22:33:02 +0000 +Subject: [PATCH] net: fix /proc/net/dev regression + +commit 2def16ae6b0c77571200f18ba4be049b03d75579 upstream. + +Commit f04565ddf52 (dev: use name hash for dev_seq_ops) added a second +regression, as some devices are missing from /proc/net/dev if many +devices are defined. + +When seq_file buffer is filled, the last ->next/show() method is +canceled (pos value is reverted to value prior ->next() call) + +Problem is after above commit, we dont restart the lookup at right +position in ->start() method. + +Fix this by removing the internal 'pos' pointer added in commit, since +we need to use the 'loff_t *pos' provided by seq_file layer. + +This also reverts commit 5cac98dd0 (net: Fix corruption +in /proc/*/net/dev_mcast), since its not needed anymore. + +Reported-by: Ben Greear +Signed-off-by: Eric Dumazet +Cc: Mihai Maruseac +Tested-by: Ben Greear +Signed-off-by: David S. Miller +--- + include/linux/netdevice.h | 2 -- + net/core/dev.c | 58 ++++++++++----------------------------------- + net/core/dev_addr_lists.c | 3 ++- + 3 files changed, 15 insertions(+), 48 deletions(-) + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 1f77540..5cbaa20 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2604,8 +2604,6 @@ extern void net_disable_timestamp(void); + extern void *dev_seq_start(struct seq_file *seq, loff_t *pos); + extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos); + extern void dev_seq_stop(struct seq_file *seq, void *v); +-extern int dev_seq_open_ops(struct inode *inode, struct file *file, +- const struct seq_operations *ops); + #endif + + extern int netdev_class_create_file(struct class_attribute *class_attr); +diff --git a/net/core/dev.c b/net/core/dev.c +index 6c7dc9d..c25d453 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4028,54 +4028,41 @@ static int dev_ifconf(struct net *net, char __user *arg) + + #ifdef CONFIG_PROC_FS + +-#define BUCKET_SPACE (32 - NETDEV_HASHBITS) +- +-struct dev_iter_state { +- struct seq_net_private p; +- unsigned int pos; /* bucket << BUCKET_SPACE + offset */ +-}; ++#define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1) + + #define get_bucket(x) ((x) >> BUCKET_SPACE) + #define get_offset(x) ((x) & ((1 << BUCKET_SPACE) - 1)) + #define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o)) + +-static inline struct net_device *dev_from_same_bucket(struct seq_file *seq) ++static inline struct net_device *dev_from_same_bucket(struct seq_file *seq, loff_t *pos) + { +- struct dev_iter_state *state = seq->private; + struct net *net = seq_file_net(seq); + struct net_device *dev; + struct hlist_node *p; + struct hlist_head *h; +- unsigned int count, bucket, offset; ++ unsigned int count = 0, offset = get_offset(*pos); + +- bucket = get_bucket(state->pos); +- offset = get_offset(state->pos); +- h = &net->dev_name_head[bucket]; +- count = 0; ++ h = &net->dev_name_head[get_bucket(*pos)]; + hlist_for_each_entry_rcu(dev, p, h, name_hlist) { +- if (count++ == offset) { +- state->pos = set_bucket_offset(bucket, count); ++ if (++count == offset) + return dev; +- } + } + + return NULL; + } + +-static inline struct net_device *dev_from_new_bucket(struct seq_file *seq) ++static inline struct net_device *dev_from_bucket(struct seq_file *seq, loff_t *pos) + { +- struct dev_iter_state *state = seq->private; + struct net_device *dev; + unsigned int bucket; + +- bucket = get_bucket(state->pos); + do { +- dev = dev_from_same_bucket(seq); ++ dev = dev_from_same_bucket(seq, pos); + if (dev) + return dev; + +- bucket++; +- state->pos = set_bucket_offset(bucket, 0); ++ bucket = get_bucket(*pos) + 1; ++ *pos = set_bucket_offset(bucket, 1); + } while (bucket < NETDEV_HASHENTRIES); + + return NULL; +@@ -4088,33 +4075,20 @@ static inline struct net_device *dev_from_new_bucket(struct seq_file *seq) + void *dev_seq_start(struct seq_file *seq, loff_t *pos) + __acquires(RCU) + { +- struct dev_iter_state *state = seq->private; +- + rcu_read_lock(); + if (!*pos) + return SEQ_START_TOKEN; + +- /* check for end of the hash */ +- if (state->pos == 0 && *pos > 1) ++ if (get_bucket(*pos) >= NETDEV_HASHENTRIES) + return NULL; + +- return dev_from_new_bucket(seq); ++ return dev_from_bucket(seq, pos); + } + + void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) + { +- struct net_device *dev; +- + ++*pos; +- +- if (v == SEQ_START_TOKEN) +- return dev_from_new_bucket(seq); +- +- dev = dev_from_same_bucket(seq); +- if (dev) +- return dev; +- +- return dev_from_new_bucket(seq); ++ return dev_from_bucket(seq, pos); + } + + void dev_seq_stop(struct seq_file *seq, void *v) +@@ -4213,13 +4187,7 @@ static const struct seq_operations dev_seq_ops = { + static int dev_seq_open(struct inode *inode, struct file *file) + { + return seq_open_net(inode, file, &dev_seq_ops, +- sizeof(struct dev_iter_state)); +-} +- +-int dev_seq_open_ops(struct inode *inode, struct file *file, +- const struct seq_operations *ops) +-{ +- return seq_open_net(inode, file, ops, sizeof(struct dev_iter_state)); ++ sizeof(struct seq_net_private)); + } + + static const struct file_operations dev_seq_fops = { +diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c +index 29c07fe..626698f 100644 +--- a/net/core/dev_addr_lists.c ++++ b/net/core/dev_addr_lists.c +@@ -696,7 +696,8 @@ static const struct seq_operations dev_mc_seq_ops = { + + static int dev_mc_seq_open(struct inode *inode, struct file *file) + { +- return dev_seq_open_ops(inode, file, &dev_mc_seq_ops); ++ return seq_open_net(inode, file, &dev_mc_seq_ops, ++ sizeof(struct seq_net_private)); + } + + static const struct file_operations dev_mc_seq_fops = { +-- +1.7.9.5 + diff --git a/debian/patches/series/base b/debian/patches/series/base index b1d599e29..1fba75348 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -81,6 +81,7 @@ + features/all/fs-hardlink-creation-restriction-cleanup.patch + bugfix/all/Don-t-limit-non-nested-epoll-paths.patch + bugfix/all/kbuild-do-not-check-for-ancient-modutils-tools.patch ++ bugfix/x86/ioat-fix-size-of-completion-for-Xen.patch # Temporary, until the original change has been tested some more + debian/revert-CIFS-Respect-negotiated-MaxMpxCount.patch @@ -90,3 +91,4 @@ # Temporary, until the next ABI bump + debian/revert-rtc-Provide-flag-for-rtc-devices-that-don-t-s.patch ++ bugfix/all/net-fix-proc-net-dev-regression.patch