summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2013-12-09 09:50:52 -0500
committerAnthony G. Basile <blueness@gentoo.org>2013-12-09 09:50:52 -0500
commitf5f76b7f471550ff8e1e5a46eb619cd1b0cbacfb (patch)
tree6e69b9aaff14fb9f90e8c8b13ccd43d04c56e020 /3.12.4/1003_linux-3.12.4.patch
parentGrsec/PaX: 3.0-{3.2.53,3.12.2}-201312032145 (diff)
downloadhardened-patchset-f5f76b7f471550ff8e1e5a46eb619cd1b0cbacfb.tar.gz
hardened-patchset-f5f76b7f471550ff8e1e5a46eb619cd1b0cbacfb.tar.bz2
hardened-patchset-f5f76b7f471550ff8e1e5a46eb619cd1b0cbacfb.zip
Grsec/PaX: 3.0-{2.6.32,3.2.53,3.12.4}-2013120820131208
Diffstat (limited to '3.12.4/1003_linux-3.12.4.patch')
-rw-r--r--3.12.4/1003_linux-3.12.4.patch4725
1 files changed, 4725 insertions, 0 deletions
diff --git a/3.12.4/1003_linux-3.12.4.patch b/3.12.4/1003_linux-3.12.4.patch
new file mode 100644
index 0000000..819cfed
--- /dev/null
+++ b/3.12.4/1003_linux-3.12.4.patch
@@ -0,0 +1,4725 @@
+diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
+index a46d785..7d8dc93 100644
+--- a/Documentation/networking/ip-sysctl.txt
++++ b/Documentation/networking/ip-sysctl.txt
+@@ -588,9 +588,6 @@ tcp_limit_output_bytes - INTEGER
+ typical pfifo_fast qdiscs.
+ tcp_limit_output_bytes limits the number of bytes on qdisc
+ or device to reduce artificial RTT/cwnd and reduce bufferbloat.
+- Note: For GSO/TSO enabled flows, we try to have at least two
+- packets in flight. Reducing tcp_limit_output_bytes might also
+- reduce the size of individual GSO packet (64KB being the max)
+ Default: 131072
+
+ tcp_challenge_ack_limit - INTEGER
+diff --git a/Makefile b/Makefile
+index b28bc57..3b7165e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 12
+-SUBLEVEL = 3
++SUBLEVEL = 4
+ EXTRAVERSION =
+ NAME = One Giant Leap for Frogkind
+
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index 516593e..26328e8 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -788,5 +788,7 @@ void bpf_jit_free(struct sk_filter *fp)
+ if (fp->bpf_func != sk_run_filter) {
+ INIT_WORK(&fp->work, bpf_jit_free_deferred);
+ schedule_work(&fp->work);
++ } else {
++ kfree(fp);
+ }
+ }
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 0c611d8..fce4b93 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -741,9 +741,17 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
+
+ q->sg_reserved_size = INT_MAX;
+
++ /* Protect q->elevator from elevator_change */
++ mutex_lock(&q->sysfs_lock);
++
+ /* init elevator */
+- if (elevator_init(q, NULL))
++ if (elevator_init(q, NULL)) {
++ mutex_unlock(&q->sysfs_lock);
+ return NULL;
++ }
++
++ mutex_unlock(&q->sysfs_lock);
++
+ return q;
+ }
+ EXPORT_SYMBOL(blk_init_allocated_queue);
+diff --git a/block/elevator.c b/block/elevator.c
+index 2bcbd8c..b7ff286 100644
+--- a/block/elevator.c
++++ b/block/elevator.c
+@@ -186,6 +186,12 @@ int elevator_init(struct request_queue *q, char *name)
+ struct elevator_type *e = NULL;
+ int err;
+
++ /*
++ * q->sysfs_lock must be held to provide mutual exclusion between
++ * elevator_switch() and here.
++ */
++ lockdep_assert_held(&q->sysfs_lock);
++
+ if (unlikely(q->elevator))
+ return 0;
+
+@@ -959,7 +965,7 @@ fail_init:
+ /*
+ * Switch this queue to the given IO scheduler.
+ */
+-int elevator_change(struct request_queue *q, const char *name)
++static int __elevator_change(struct request_queue *q, const char *name)
+ {
+ char elevator_name[ELV_NAME_MAX];
+ struct elevator_type *e;
+@@ -981,6 +987,18 @@ int elevator_change(struct request_queue *q, const char *name)
+
+ return elevator_switch(q, e);
+ }
++
++int elevator_change(struct request_queue *q, const char *name)
++{
++ int ret;
++
++ /* Protect q->elevator from elevator_init() */
++ mutex_lock(&q->sysfs_lock);
++ ret = __elevator_change(q, name);
++ mutex_unlock(&q->sysfs_lock);
++
++ return ret;
++}
+ EXPORT_SYMBOL(elevator_change);
+
+ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
+@@ -991,7 +1009,7 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
+ if (!q->elevator)
+ return count;
+
+- ret = elevator_change(q, name);
++ ret = __elevator_change(q, name);
+ if (!ret)
+ return count;
+
+diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
+index 0262210..8502462 100644
+--- a/crypto/algif_hash.c
++++ b/crypto/algif_hash.c
+@@ -114,6 +114,9 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
+ struct hash_ctx *ctx = ask->private;
+ int err;
+
++ if (flags & MSG_SENDPAGE_NOTLAST)
++ flags |= MSG_MORE;
++
+ lock_sock(sk);
+ sg_init_table(ctx->sgl.sg, 1);
+ sg_set_page(ctx->sgl.sg, page, size, offset);
+@@ -161,8 +164,6 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock,
+ else if (len < ds)
+ msg->msg_flags |= MSG_TRUNC;
+
+- msg->msg_namelen = 0;
+-
+ lock_sock(sk);
+ if (ctx->more) {
+ ctx->more = 0;
+diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
+index a1c4f0a..a19c027 100644
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -378,6 +378,9 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page,
+ struct skcipher_sg_list *sgl;
+ int err = -EINVAL;
+
++ if (flags & MSG_SENDPAGE_NOTLAST)
++ flags |= MSG_MORE;
++
+ lock_sock(sk);
+ if (!ctx->more && ctx->used)
+ goto unlock;
+@@ -432,7 +435,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
+ long copied = 0;
+
+ lock_sock(sk);
+- msg->msg_namelen = 0;
+ for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
+ iovlen--, iov++) {
+ unsigned long seglen = iov->iov_len;
+diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
+index 272f009..1bdf104 100644
+--- a/drivers/atm/idt77252.c
++++ b/drivers/atm/idt77252.c
+@@ -3511,7 +3511,7 @@ static int init_card(struct atm_dev *dev)
+ tmp = dev_get_by_name(&init_net, tname); /* jhs: was "tmp = dev_get(tname);" */
+ if (tmp) {
+ memcpy(card->atmdev->esi, tmp->dev_addr, 6);
+-
++ dev_put(tmp);
+ printk("%s: ESI %pM\n", card->name, card->atmdev->esi);
+ }
+ /*
+diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
+index c73fc2b..18c5b9b 100644
+--- a/drivers/connector/cn_proc.c
++++ b/drivers/connector/cn_proc.c
+@@ -32,11 +32,23 @@
+ #include <linux/atomic.h>
+ #include <linux/pid_namespace.h>
+
+-#include <asm/unaligned.h>
+-
+ #include <linux/cn_proc.h>
+
+-#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
++/*
++ * Size of a cn_msg followed by a proc_event structure. Since the
++ * sizeof struct cn_msg is a multiple of 4 bytes, but not 8 bytes, we
++ * add one 4-byte word to the size here, and then start the actual
++ * cn_msg structure 4 bytes into the stack buffer. The result is that
++ * the immediately following proc_event structure is aligned to 8 bytes.
++ */
++#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event) + 4)
++
++/* See comment above; we test our assumption about sizeof struct cn_msg here. */
++static inline struct cn_msg *buffer_to_cn_msg(__u8 *buffer)
++{
++ BUILD_BUG_ON(sizeof(struct cn_msg) != 20);
++ return (struct cn_msg *)(buffer + 4);
++}
+
+ static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
+ static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
+@@ -56,19 +68,19 @@ void proc_fork_connector(struct task_struct *task)
+ {
+ struct cn_msg *msg;
+ struct proc_event *ev;
+- __u8 buffer[CN_PROC_MSG_SIZE];
++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ struct timespec ts;
+ struct task_struct *parent;
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+- msg = (struct cn_msg *)buffer;
++ msg = buffer_to_cn_msg(buffer);
+ ev = (struct proc_event *)msg->data;
+ memset(&ev->event_data, 0, sizeof(ev->event_data));
+ get_seq(&msg->seq, &ev->cpu);
+ ktime_get_ts(&ts); /* get high res monotonic timestamp */
+- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++ ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->what = PROC_EVENT_FORK;
+ rcu_read_lock();
+ parent = rcu_dereference(task->real_parent);
+@@ -91,17 +103,17 @@ void proc_exec_connector(struct task_struct *task)
+ struct cn_msg *msg;
+ struct proc_event *ev;
+ struct timespec ts;
+- __u8 buffer[CN_PROC_MSG_SIZE];
++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+- msg = (struct cn_msg *)buffer;
++ msg = buffer_to_cn_msg(buffer);
+ ev = (struct proc_event *)msg->data;
+ memset(&ev->event_data, 0, sizeof(ev->event_data));
+ get_seq(&msg->seq, &ev->cpu);
+ ktime_get_ts(&ts); /* get high res monotonic timestamp */
+- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++ ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->what = PROC_EVENT_EXEC;
+ ev->event_data.exec.process_pid = task->pid;
+ ev->event_data.exec.process_tgid = task->tgid;
+@@ -117,14 +129,14 @@ void proc_id_connector(struct task_struct *task, int which_id)
+ {
+ struct cn_msg *msg;
+ struct proc_event *ev;
+- __u8 buffer[CN_PROC_MSG_SIZE];
++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ struct timespec ts;
+ const struct cred *cred;
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+- msg = (struct cn_msg *)buffer;
++ msg = buffer_to_cn_msg(buffer);
+ ev = (struct proc_event *)msg->data;
+ memset(&ev->event_data, 0, sizeof(ev->event_data));
+ ev->what = which_id;
+@@ -145,7 +157,7 @@ void proc_id_connector(struct task_struct *task, int which_id)
+ rcu_read_unlock();
+ get_seq(&msg->seq, &ev->cpu);
+ ktime_get_ts(&ts); /* get high res monotonic timestamp */
+- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++ ev->timestamp_ns = timespec_to_ns(&ts);
+
+ memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+ msg->ack = 0; /* not used */
+@@ -159,17 +171,17 @@ void proc_sid_connector(struct task_struct *task)
+ struct cn_msg *msg;
+ struct proc_event *ev;
+ struct timespec ts;
+- __u8 buffer[CN_PROC_MSG_SIZE];
++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+- msg = (struct cn_msg *)buffer;
++ msg = buffer_to_cn_msg(buffer);
+ ev = (struct proc_event *)msg->data;
+ memset(&ev->event_data, 0, sizeof(ev->event_data));
+ get_seq(&msg->seq, &ev->cpu);
+ ktime_get_ts(&ts); /* get high res monotonic timestamp */
+- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++ ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->what = PROC_EVENT_SID;
+ ev->event_data.sid.process_pid = task->pid;
+ ev->event_data.sid.process_tgid = task->tgid;
+@@ -186,17 +198,17 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
+ struct cn_msg *msg;
+ struct proc_event *ev;
+ struct timespec ts;
+- __u8 buffer[CN_PROC_MSG_SIZE];
++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+- msg = (struct cn_msg *)buffer;
++ msg = buffer_to_cn_msg(buffer);
+ ev = (struct proc_event *)msg->data;
+ memset(&ev->event_data, 0, sizeof(ev->event_data));
+ get_seq(&msg->seq, &ev->cpu);
+ ktime_get_ts(&ts); /* get high res monotonic timestamp */
+- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++ ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->what = PROC_EVENT_PTRACE;
+ ev->event_data.ptrace.process_pid = task->pid;
+ ev->event_data.ptrace.process_tgid = task->tgid;
+@@ -221,17 +233,17 @@ void proc_comm_connector(struct task_struct *task)
+ struct cn_msg *msg;
+ struct proc_event *ev;
+ struct timespec ts;
+- __u8 buffer[CN_PROC_MSG_SIZE];
++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+- msg = (struct cn_msg *)buffer;
++ msg = buffer_to_cn_msg(buffer);
+ ev = (struct proc_event *)msg->data;
+ memset(&ev->event_data, 0, sizeof(ev->event_data));
+ get_seq(&msg->seq, &ev->cpu);
+ ktime_get_ts(&ts); /* get high res monotonic timestamp */
+- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++ ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->what = PROC_EVENT_COMM;
+ ev->event_data.comm.process_pid = task->pid;
+ ev->event_data.comm.process_tgid = task->tgid;
+@@ -248,18 +260,18 @@ void proc_coredump_connector(struct task_struct *task)
+ {
+ struct cn_msg *msg;
+ struct proc_event *ev;
+- __u8 buffer[CN_PROC_MSG_SIZE];
++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ struct timespec ts;
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+- msg = (struct cn_msg *)buffer;
++ msg = buffer_to_cn_msg(buffer);
+ ev = (struct proc_event *)msg->data;
+ memset(&ev->event_data, 0, sizeof(ev->event_data));
+ get_seq(&msg->seq, &ev->cpu);
+ ktime_get_ts(&ts); /* get high res monotonic timestamp */
+- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++ ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->what = PROC_EVENT_COREDUMP;
+ ev->event_data.coredump.process_pid = task->pid;
+ ev->event_data.coredump.process_tgid = task->tgid;
+@@ -275,18 +287,18 @@ void proc_exit_connector(struct task_struct *task)
+ {
+ struct cn_msg *msg;
+ struct proc_event *ev;
+- __u8 buffer[CN_PROC_MSG_SIZE];
++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ struct timespec ts;
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+- msg = (struct cn_msg *)buffer;
++ msg = buffer_to_cn_msg(buffer);
+ ev = (struct proc_event *)msg->data;
+ memset(&ev->event_data, 0, sizeof(ev->event_data));
+ get_seq(&msg->seq, &ev->cpu);
+ ktime_get_ts(&ts); /* get high res monotonic timestamp */
+- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++ ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->what = PROC_EVENT_EXIT;
+ ev->event_data.exit.process_pid = task->pid;
+ ev->event_data.exit.process_tgid = task->tgid;
+@@ -312,18 +324,18 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
+ {
+ struct cn_msg *msg;
+ struct proc_event *ev;
+- __u8 buffer[CN_PROC_MSG_SIZE];
++ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+ struct timespec ts;
+
+ if (atomic_read(&proc_event_num_listeners) < 1)
+ return;
+
+- msg = (struct cn_msg *)buffer;
++ msg = buffer_to_cn_msg(buffer);
+ ev = (struct proc_event *)msg->data;
+ memset(&ev->event_data, 0, sizeof(ev->event_data));
+ msg->seq = rcvd_seq;
+ ktime_get_ts(&ts); /* get high res monotonic timestamp */
+- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++ ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->cpu = -1;
+ ev->what = PROC_EVENT_NONE;
+ ev->event_data.ack.err = err;
+diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
+index 06022e3..615c5b2 100644
+--- a/drivers/gpu/drm/radeon/r600_hdmi.c
++++ b/drivers/gpu/drm/radeon/r600_hdmi.c
+@@ -24,6 +24,7 @@
+ * Authors: Christian König
+ */
+ #include <linux/hdmi.h>
++#include <linux/gcd.h>
+ #include <drm/drmP.h>
+ #include <drm/radeon_drm.h>
+ #include "radeon.h"
+@@ -57,35 +58,57 @@ enum r600_hdmi_iec_status_bits {
+ static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
+ /* 32kHz 44.1kHz 48kHz */
+ /* Clock N CTS N CTS N CTS */
+- { 25175, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */
++ { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */
+ { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
+ { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
+ { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
+ { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
+ { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
+- { 74176, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */
++ { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */
+ { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
+- { 148352, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */
++ { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */
+ { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
+- { 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */
+ };
+
++
+ /*
+- * calculate CTS value if it's not found in the table
++ * calculate CTS and N values if they are not found in the table
+ */
+-static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq)
++static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq)
+ {
+- u64 n;
+- u32 d;
+-
+- if (*CTS == 0) {
+- n = (u64)clock * (u64)N * 1000ULL;
+- d = 128 * freq;
+- do_div(n, d);
+- *CTS = n;
+- }
+- DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
+- N, *CTS, freq);
++ int n, cts;
++ unsigned long div, mul;
++
++ /* Safe, but overly large values */
++ n = 128 * freq;
++ cts = clock * 1000;
++
++ /* Smallest valid fraction */
++ div = gcd(n, cts);
++
++ n /= div;
++ cts /= div;
++
++ /*
++ * The optimal N is 128*freq/1000. Calculate the closest larger
++ * value that doesn't truncate any bits.
++ */
++ mul = ((128*freq/1000) + (n-1))/n;
++
++ n *= mul;
++ cts *= mul;
++
++ /* Check that we are in spec (not always possible) */
++ if (n < (128*freq/1500))
++ printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n");
++ if (n > (128*freq/300))
++ printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n");
++
++ *N = n;
++ *CTS = cts;
++
++ DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n",
++ *N, *CTS, freq);
+ }
+
+ struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
+@@ -93,15 +116,16 @@ struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
+ struct radeon_hdmi_acr res;
+ u8 i;
+
+- for (i = 0; r600_hdmi_predefined_acr[i].clock != clock &&
+- r600_hdmi_predefined_acr[i].clock != 0; i++)
+- ;
+- res = r600_hdmi_predefined_acr[i];
++ /* Precalculated values for common clocks */
++ for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) {
++ if (r600_hdmi_predefined_acr[i].clock == clock)
++ return r600_hdmi_predefined_acr[i];
++ }
+
+- /* In case some CTS are missing */
+- r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000);
+- r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100);
+- r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000);
++ /* And odd clocks get manually calculated */
++ r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
++ r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
++ r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
+
+ return res;
+ }
+diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c
+index f042a6c..55e4920 100644
+--- a/drivers/hid/hid-elo.c
++++ b/drivers/hid/hid-elo.c
+@@ -181,7 +181,40 @@ fail:
+ */
+ static bool elo_broken_firmware(struct usb_device *dev)
+ {
+- return use_fw_quirk && le16_to_cpu(dev->descriptor.bcdDevice) == 0x10d;
++ struct usb_device *hub = dev->parent;
++ struct usb_device *child = NULL;
++ u16 fw_lvl = le16_to_cpu(dev->descriptor.bcdDevice);
++ u16 child_vid, child_pid;
++ int i;
++
++ if (!use_fw_quirk)
++ return false;
++ if (fw_lvl != 0x10d)
++ return false;
++
++ /* iterate sibling devices of the touch controller */
++ usb_hub_for_each_child(hub, i, child) {
++ child_vid = le16_to_cpu(child->descriptor.idVendor);
++ child_pid = le16_to_cpu(child->descriptor.idProduct);
++
++ /*
++ * If one of the devices below is present attached as a sibling of
++ * the touch controller then this is a newer IBM 4820 monitor that
++ * does not need the IBM-requested workaround if fw level is
++ * 0x010d - aka 'M'.
++ * No other HW can have this combination.
++ */
++ if (child_vid==0x04b3) {
++ switch (child_pid) {
++ case 0x4676: /* 4820 21x Video */
++ case 0x4677: /* 4820 51x Video */
++ case 0x4678: /* 4820 2Lx Video */
++ case 0x4679: /* 4820 5Lx Video */
++ return false;
++ }
++ }
++ }
++ return true;
+ }
+
+ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
+diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
+index 1bfd292..06eb45f 100644
+--- a/drivers/hid/hid-lg.c
++++ b/drivers/hid/hid-lg.c
+@@ -47,6 +47,7 @@
+ #define DFP_RDESC_ORIG_SIZE 97
+ #define FV_RDESC_ORIG_SIZE 130
+ #define MOMO_RDESC_ORIG_SIZE 87
++#define MOMO2_RDESC_ORIG_SIZE 87
+
+ /* Fixed report descriptors for Logitech Driving Force (and Pro)
+ * wheel controllers
+@@ -284,6 +285,54 @@ static __u8 momo_rdesc_fixed[] = {
+ 0xC0 /* End Collection */
+ };
+
++static __u8 momo2_rdesc_fixed[] = {
++0x05, 0x01, /* Usage Page (Desktop), */
++0x09, 0x04, /* Usage (Joystik), */
++0xA1, 0x01, /* Collection (Application), */
++0xA1, 0x02, /* Collection (Logical), */
++0x95, 0x01, /* Report Count (1), */
++0x75, 0x0A, /* Report Size (10), */
++0x15, 0x00, /* Logical Minimum (0), */
++0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
++0x35, 0x00, /* Physical Minimum (0), */
++0x46, 0xFF, 0x03, /* Physical Maximum (1023), */
++0x09, 0x30, /* Usage (X), */
++0x81, 0x02, /* Input (Variable), */
++0x95, 0x0A, /* Report Count (10), */
++0x75, 0x01, /* Report Size (1), */
++0x25, 0x01, /* Logical Maximum (1), */
++0x45, 0x01, /* Physical Maximum (1), */
++0x05, 0x09, /* Usage Page (Button), */
++0x19, 0x01, /* Usage Minimum (01h), */
++0x29, 0x0A, /* Usage Maximum (0Ah), */
++0x81, 0x02, /* Input (Variable), */
++0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
++0x09, 0x00, /* Usage (00h), */
++0x95, 0x04, /* Report Count (4), */
++0x81, 0x02, /* Input (Variable), */
++0x95, 0x01, /* Report Count (1), */
++0x75, 0x08, /* Report Size (8), */
++0x26, 0xFF, 0x00, /* Logical Maximum (255), */
++0x46, 0xFF, 0x00, /* Physical Maximum (255), */
++0x09, 0x01, /* Usage (01h), */
++0x81, 0x02, /* Input (Variable), */
++0x05, 0x01, /* Usage Page (Desktop), */
++0x09, 0x31, /* Usage (Y), */
++0x81, 0x02, /* Input (Variable), */
++0x09, 0x32, /* Usage (Z), */
++0x81, 0x02, /* Input (Variable), */
++0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
++0x09, 0x00, /* Usage (00h), */
++0x81, 0x02, /* Input (Variable), */
++0xC0, /* End Collection, */
++0xA1, 0x02, /* Collection (Logical), */
++0x09, 0x02, /* Usage (02h), */
++0x95, 0x07, /* Report Count (7), */
++0x91, 0x02, /* Output (Variable), */
++0xC0, /* End Collection, */
++0xC0 /* End Collection */
++};
++
+ /*
+ * Certain Logitech keyboards send in report #3 keys which are far
+ * above the logical maximum described in descriptor. This extends
+@@ -343,6 +392,15 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ }
+ break;
+
++ case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
++ if (*rsize == MOMO2_RDESC_ORIG_SIZE) {
++ hid_info(hdev,
++ "fixing up Logitech Momo Racing Force (Black) report descriptor\n");
++ rdesc = momo2_rdesc_fixed;
++ *rsize = sizeof(momo2_rdesc_fixed);
++ }
++ break;
++
+ case USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL:
+ if (*rsize == FV_RDESC_ORIG_SIZE) {
+ hid_info(hdev,
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index 15e9b57..40203ad 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -782,7 +782,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
+ int offset;
+
+ BUG_ON(!domain->pgd);
+- BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width);
++
++ if (addr_width < BITS_PER_LONG && pfn >> addr_width)
++ /* Address beyond IOMMU's addressing capabilities. */
++ return NULL;
++
+ parent = domain->pgd;
+
+ while (level > 0) {
+diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
+index f71673d..b97d70b 100644
+--- a/drivers/iommu/intel_irq_remapping.c
++++ b/drivers/iommu/intel_irq_remapping.c
+@@ -525,12 +525,13 @@ static int __init intel_irq_remapping_supported(void)
+ if (disable_irq_remap)
+ return 0;
+ if (irq_remap_broken) {
+- WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
+- "This system BIOS has enabled interrupt remapping\n"
+- "on a chipset that contains an erratum making that\n"
+- "feature unstable. To maintain system stability\n"
+- "interrupt remapping is being disabled. Please\n"
+- "contact your BIOS vendor for an update\n");
++ printk(KERN_WARNING
++ "This system BIOS has enabled interrupt remapping\n"
++ "on a chipset that contains an erratum making that\n"
++ "feature unstable. To maintain system stability\n"
++ "interrupt remapping is being disabled. Please\n"
++ "contact your BIOS vendor for an update\n");
++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
+ disable_irq_remap = 1;
+ return 0;
+ }
+diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
+index baf2686..02125e6 100644
+--- a/drivers/isdn/isdnloop/isdnloop.c
++++ b/drivers/isdn/isdnloop/isdnloop.c
+@@ -1083,8 +1083,10 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp)
+ spin_unlock_irqrestore(&card->isdnloop_lock, flags);
+ return -ENOMEM;
+ }
+- for (i = 0; i < 3; i++)
+- strcpy(card->s0num[i], sdef.num[i]);
++ for (i = 0; i < 3; i++) {
++ strlcpy(card->s0num[i], sdef.num[i],
++ sizeof(card->s0num[0]));
++ }
+ break;
+ case ISDN_PTYPE_1TR6:
+ if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95",
+@@ -1097,7 +1099,7 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp)
+ spin_unlock_irqrestore(&card->isdnloop_lock, flags);
+ return -ENOMEM;
+ }
+- strcpy(card->s0num[0], sdef.num[0]);
++ strlcpy(card->s0num[0], sdef.num[0], sizeof(card->s0num[0]));
+ card->s0num[1][0] = '\0';
+ card->s0num[2][0] = '\0';
+ break;
+diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
+index e47dcb9..5cefb47 100644
+--- a/drivers/isdn/mISDN/socket.c
++++ b/drivers/isdn/mISDN/socket.c
+@@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+ {
+ struct sk_buff *skb;
+ struct sock *sk = sock->sk;
+- struct sockaddr_mISDN *maddr;
+
+ int copied, err;
+
+@@ -135,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (!skb)
+ return err;
+
+- if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
+- msg->msg_namelen = sizeof(struct sockaddr_mISDN);
+- maddr = (struct sockaddr_mISDN *)msg->msg_name;
++ if (msg->msg_name) {
++ struct sockaddr_mISDN *maddr = msg->msg_name;
++
+ maddr->family = AF_ISDN;
+ maddr->dev = _pms(sk)->dev->id;
+ if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
+@@ -150,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+ maddr->sapi = _pms(sk)->ch.addr & 0xFF;
+ maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF;
+ }
+- } else {
+- if (msg->msg_namelen)
+- printk(KERN_WARNING "%s: too small namelen %d\n",
+- __func__, msg->msg_namelen);
+- msg->msg_namelen = 0;
++ msg->msg_namelen = sizeof(*maddr);
+ }
+
+ copied = skb->len + MISDN_HEADER_LEN;
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index e4109f6..8a0665d 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -5214,15 +5214,18 @@ raid5_show_group_thread_cnt(struct mddev *mddev, char *page)
+ return 0;
+ }
+
+-static int alloc_thread_groups(struct r5conf *conf, int cnt);
++static int alloc_thread_groups(struct r5conf *conf, int cnt,
++ int *group_cnt,
++ int *worker_cnt_per_group,
++ struct r5worker_group **worker_groups);
+ static ssize_t
+ raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)
+ {
+ struct r5conf *conf = mddev->private;
+ unsigned long new;
+ int err;
+- struct r5worker_group *old_groups;
+- int old_group_cnt;
++ struct r5worker_group *new_groups, *old_groups;
++ int group_cnt, worker_cnt_per_group;
+
+ if (len >= PAGE_SIZE)
+ return -EINVAL;
+@@ -5238,17 +5241,19 @@ raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)
+ mddev_suspend(mddev);
+
+ old_groups = conf->worker_groups;
+- old_group_cnt = conf->worker_cnt_per_group;
+-
+ if (old_groups)
+ flush_workqueue(raid5_wq);
+
+- conf->worker_groups = NULL;
+- err = alloc_thread_groups(conf, new);
+- if (err) {
+- conf->worker_groups = old_groups;
+- conf->worker_cnt_per_group = old_group_cnt;
+- } else {
++ err = alloc_thread_groups(conf, new,
++ &group_cnt, &worker_cnt_per_group,
++ &new_groups);
++ if (!err) {
++ spin_lock_irq(&conf->device_lock);
++ conf->group_cnt = group_cnt;
++ conf->worker_cnt_per_group = worker_cnt_per_group;
++ conf->worker_groups = new_groups;
++ spin_unlock_irq(&conf->device_lock);
++
+ if (old_groups)
+ kfree(old_groups[0].workers);
+ kfree(old_groups);
+@@ -5278,33 +5283,36 @@ static struct attribute_group raid5_attrs_group = {
+ .attrs = raid5_attrs,
+ };
+
+-static int alloc_thread_groups(struct r5conf *conf, int cnt)
++static int alloc_thread_groups(struct r5conf *conf, int cnt,
++ int *group_cnt,
++ int *worker_cnt_per_group,
++ struct r5worker_group **worker_groups)
+ {
+ int i, j;
+ ssize_t size;
+ struct r5worker *workers;
+
+- conf->worker_cnt_per_group = cnt;
++ *worker_cnt_per_group = cnt;
+ if (cnt == 0) {
+- conf->worker_groups = NULL;
++ *group_cnt = 0;
++ *worker_groups = NULL;
+ return 0;
+ }
+- conf->group_cnt = num_possible_nodes();
++ *group_cnt = num_possible_nodes();
+ size = sizeof(struct r5worker) * cnt;
+- workers = kzalloc(size * conf->group_cnt, GFP_NOIO);
+- conf->worker_groups = kzalloc(sizeof(struct r5worker_group) *
+- conf->group_cnt, GFP_NOIO);
+- if (!conf->worker_groups || !workers) {
++ workers = kzalloc(size * *group_cnt, GFP_NOIO);
++ *worker_groups = kzalloc(sizeof(struct r5worker_group) *
++ *group_cnt, GFP_NOIO);
++ if (!*worker_groups || !workers) {
+ kfree(workers);
+- kfree(conf->worker_groups);
+- conf->worker_groups = NULL;
++ kfree(*worker_groups);
+ return -ENOMEM;
+ }
+
+- for (i = 0; i < conf->group_cnt; i++) {
++ for (i = 0; i < *group_cnt; i++) {
+ struct r5worker_group *group;
+
+- group = &conf->worker_groups[i];
++ group = &(*worker_groups)[i];
+ INIT_LIST_HEAD(&group->handle_list);
+ group->conf = conf;
+ group->workers = workers + i * cnt;
+@@ -5462,6 +5470,8 @@ static struct r5conf *setup_conf(struct mddev *mddev)
+ struct md_rdev *rdev;
+ struct disk_info *disk;
+ char pers_name[6];
++ int group_cnt, worker_cnt_per_group;
++ struct r5worker_group *new_group;
+
+ if (mddev->new_level != 5
+ && mddev->new_level != 4
+@@ -5496,7 +5506,12 @@ static struct r5conf *setup_conf(struct mddev *mddev)
+ if (conf == NULL)
+ goto abort;
+ /* Don't enable multi-threading by default*/
+- if (alloc_thread_groups(conf, 0))
++ if (!alloc_thread_groups(conf, 0, &group_cnt, &worker_cnt_per_group,
++ &new_group)) {
++ conf->group_cnt = group_cnt;
++ conf->worker_cnt_per_group = worker_cnt_per_group;
++ conf->worker_groups = new_group;
++ } else
+ goto abort;
+ spin_lock_init(&conf->device_lock);
+ seqcount_init(&conf->gen_lock);
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index e883bfe..dd8057d 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -3395,20 +3395,20 @@ static void bond_set_rx_mode(struct net_device *bond_dev)
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave;
+
+- ASSERT_RTNL();
+-
++ rcu_read_lock();
+ if (USES_PRIMARY(bond->params.mode)) {
+- slave = rtnl_dereference(bond->curr_active_slave);
++ slave = rcu_dereference(bond->curr_active_slave);
+ if (slave) {
+ dev_uc_sync(slave->dev, bond_dev);
+ dev_mc_sync(slave->dev, bond_dev);
+ }
+ } else {
+- bond_for_each_slave(bond, slave) {
++ bond_for_each_slave_rcu(bond, slave) {
+ dev_uc_sync_multiple(slave->dev, bond_dev);
+ dev_mc_sync_multiple(slave->dev, bond_dev);
+ }
+ }
++ rcu_read_unlock();
+ }
+
+ static int bond_neigh_init(struct neighbour *n)
+diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
+index c29b836..b60f95b 100644
+--- a/drivers/net/bonding/bond_sysfs.c
++++ b/drivers/net/bonding/bond_sysfs.c
+@@ -587,8 +587,9 @@ static ssize_t bonding_store_arp_interval(struct device *d,
+ goto out;
+ }
+ if (bond->params.mode == BOND_MODE_ALB ||
+- bond->params.mode == BOND_MODE_TLB) {
+- pr_info("%s: ARP monitoring cannot be used with ALB/TLB. Only MII monitoring is supported on %s.\n",
++ bond->params.mode == BOND_MODE_TLB ||
++ bond->params.mode == BOND_MODE_8023AD) {
++ pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n",
+ bond->dev->name, bond->dev->name);
+ ret = -EINVAL;
+ goto out;
+@@ -759,6 +760,8 @@ static ssize_t bonding_store_downdelay(struct device *d,
+ int new_value, ret = count;
+ struct bonding *bond = to_bond(d);
+
++ if (!rtnl_trylock())
++ return restart_syscall();
+ if (!(bond->params.miimon)) {
+ pr_err("%s: Unable to set down delay as MII monitoring is disabled\n",
+ bond->dev->name);
+@@ -792,6 +795,7 @@ static ssize_t bonding_store_downdelay(struct device *d,
+ }
+
+ out:
++ rtnl_unlock();
+ return ret;
+ }
+ static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
+@@ -814,6 +818,8 @@ static ssize_t bonding_store_updelay(struct device *d,
+ int new_value, ret = count;
+ struct bonding *bond = to_bond(d);
+
++ if (!rtnl_trylock())
++ return restart_syscall();
+ if (!(bond->params.miimon)) {
+ pr_err("%s: Unable to set up delay as MII monitoring is disabled\n",
+ bond->dev->name);
+@@ -847,6 +853,7 @@ static ssize_t bonding_store_updelay(struct device *d,
+ }
+
+ out:
++ rtnl_unlock();
+ return ret;
+ }
+ static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
+diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
+index 2c210ec..f2f6d85 100644
+--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
+@@ -2890,6 +2890,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
+ PHY_INTERFACE_MODE_GMII);
+ if (!mp->phy)
+ err = -ENODEV;
++ else
++ phy_addr_set(mp, mp->phy->addr);
+ } else if (pd->phy_addr != MV643XX_ETH_PHY_NONE) {
+ mp->phy = phy_scan(mp, pd->phy_addr);
+
+diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
+index a071cda..0d087b0 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
+@@ -264,6 +264,10 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
+ mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
+ mdev->port_cnt++;
+
++ /* Initialize time stamp mechanism */
++ if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
++ mlx4_en_init_timestamp(mdev);
++
+ mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
+ if (!dev->caps.comp_pool) {
+ mdev->profile.prof[i].rx_ring_num =
+@@ -301,10 +305,6 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
+ mdev->pndev[i] = NULL;
+ }
+
+- /* Initialize time stamp mechanism */
+- if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
+- mlx4_en_init_timestamp(mdev);
+-
+ return mdev;
+
+ err_mr:
+diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
+index d2e5919..0095af5 100644
+--- a/drivers/net/ethernet/realtek/8139cp.c
++++ b/drivers/net/ethernet/realtek/8139cp.c
+@@ -678,9 +678,6 @@ static void cp_tx (struct cp_private *cp)
+ le32_to_cpu(txd->opts1) & 0xffff,
+ PCI_DMA_TODEVICE);
+
+- bytes_compl += skb->len;
+- pkts_compl++;
+-
+ if (status & LastFrag) {
+ if (status & (TxError | TxFIFOUnder)) {
+ netif_dbg(cp, tx_err, cp->dev,
+@@ -702,6 +699,8 @@ static void cp_tx (struct cp_private *cp)
+ netif_dbg(cp, tx_done, cp->dev,
+ "tx done, slot %d\n", tx_tail);
+ }
++ bytes_compl += skb->len;
++ pkts_compl++;
+ dev_kfree_skb_irq(skb);
+ }
+
+diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
+index 3397cee..fb3f8dc 100644
+--- a/drivers/net/ethernet/realtek/r8169.c
++++ b/drivers/net/ethernet/realtek/r8169.c
+@@ -3465,6 +3465,11 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
+ rtl_writephy(tp, 0x14, 0x9065);
+ rtl_writephy(tp, 0x14, 0x1065);
+
++ /* Check ALDPS bit, disable it if enabled */
++ rtl_writephy(tp, 0x1f, 0x0a43);
++ if (rtl_readphy(tp, 0x10) & 0x0004)
++ rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0004);
++
+ rtl_writephy(tp, 0x1f, 0x0000);
+ }
+
+diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
+index 98eedb9..fc3e25c 100644
+--- a/drivers/net/ethernet/smsc/smc91x.h
++++ b/drivers/net/ethernet/smsc/smc91x.h
+@@ -46,7 +46,8 @@
+ defined(CONFIG_MACH_LITTLETON) ||\
+ defined(CONFIG_MACH_ZYLONITE2) ||\
+ defined(CONFIG_ARCH_VIPER) ||\
+- defined(CONFIG_MACH_STARGATE2)
++ defined(CONFIG_MACH_STARGATE2) ||\
++ defined(CONFIG_ARCH_VERSATILE)
+
+ #include <asm/mach-types.h>
+
+@@ -154,6 +155,8 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
+ #define SMC_outl(v, a, r) writel(v, (a) + (r))
+ #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
+ #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
++#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
++#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
+ #define SMC_IRQ_FLAGS (-1) /* from resource */
+
+ /* We actually can't write halfwords properly if not word aligned */
+@@ -206,23 +209,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
+ #define RPC_LSA_DEFAULT RPC_LED_TX_RX
+ #define RPC_LSB_DEFAULT RPC_LED_100_10
+
+-#elif defined(CONFIG_ARCH_VERSATILE)
+-
+-#define SMC_CAN_USE_8BIT 1
+-#define SMC_CAN_USE_16BIT 1
+-#define SMC_CAN_USE_32BIT 1
+-#define SMC_NOWAIT 1
+-
+-#define SMC_inb(a, r) readb((a) + (r))
+-#define SMC_inw(a, r) readw((a) + (r))
+-#define SMC_inl(a, r) readl((a) + (r))
+-#define SMC_outb(v, a, r) writeb(v, (a) + (r))
+-#define SMC_outw(v, a, r) writew(v, (a) + (r))
+-#define SMC_outl(v, a, r) writel(v, (a) + (r))
+-#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
+-#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
+-#define SMC_IRQ_FLAGS (-1) /* from resource */
+-
+ #elif defined(CONFIG_MN10300)
+
+ /*
+diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
+index d022bf9..ad61d26 100644
+--- a/drivers/net/ethernet/via/via-velocity.c
++++ b/drivers/net/ethernet/via/via-velocity.c
+@@ -2172,16 +2172,13 @@ static int velocity_poll(struct napi_struct *napi, int budget)
+ unsigned int rx_done;
+ unsigned long flags;
+
+- spin_lock_irqsave(&vptr->lock, flags);
+ /*
+ * Do rx and tx twice for performance (taken from the VIA
+ * out-of-tree driver).
+ */
+- rx_done = velocity_rx_srv(vptr, budget / 2);
+- velocity_tx_srv(vptr);
+- rx_done += velocity_rx_srv(vptr, budget - rx_done);
++ rx_done = velocity_rx_srv(vptr, budget);
++ spin_lock_irqsave(&vptr->lock, flags);
+ velocity_tx_srv(vptr);
+-
+ /* If budget not fully consumed, exit the polling mode */
+ if (rx_done < budget) {
+ napi_complete(napi);
+@@ -2342,6 +2339,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
+ if (ret < 0)
+ goto out_free_tmp_vptr_1;
+
++ napi_disable(&vptr->napi);
++
+ spin_lock_irqsave(&vptr->lock, flags);
+
+ netif_stop_queue(dev);
+@@ -2362,6 +2361,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
+
+ velocity_give_many_rx_descs(vptr);
+
++ napi_enable(&vptr->napi);
++
+ mac_enable_int(vptr->mac_regs);
+ netif_start_queue(dev);
+
+diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
+index 9dccb1e..dc76670 100644
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -628,6 +628,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
+ const struct iovec *iv, unsigned long total_len,
+ size_t count, int noblock)
+ {
++ int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN);
+ struct sk_buff *skb;
+ struct macvlan_dev *vlan;
+ unsigned long len = total_len;
+@@ -670,6 +671,8 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
+
+ if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) {
+ copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN;
++ if (copylen > good_linear)
++ copylen = good_linear;
+ linear = copylen;
+ if (iov_pages(iv, vnet_hdr_len + copylen, count)
+ <= MAX_SKB_FRAGS)
+@@ -678,7 +681,10 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
+
+ if (!zerocopy) {
+ copylen = len;
+- linear = vnet_hdr.hdr_len;
++ if (vnet_hdr.hdr_len > good_linear)
++ linear = good_linear;
++ else
++ linear = vnet_hdr.hdr_len;
+ }
+
+ skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, copylen,
+diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
+index 5f66e30..82ee6ed 100644
+--- a/drivers/net/ppp/pppoe.c
++++ b/drivers/net/ppp/pppoe.c
+@@ -979,8 +979,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (error < 0)
+ goto end;
+
+- m->msg_namelen = 0;
+-
+ if (skb) {
+ total_len = min_t(size_t, total_len, skb->len);
+ error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
+diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
+index 50e43e6..6327df2 100644
+--- a/drivers/net/team/team.c
++++ b/drivers/net/team/team.c
+@@ -1366,6 +1366,8 @@ static int team_user_linkup_option_get(struct team *team,
+ return 0;
+ }
+
++static void __team_carrier_check(struct team *team);
++
+ static int team_user_linkup_option_set(struct team *team,
+ struct team_gsetter_ctx *ctx)
+ {
+@@ -1373,6 +1375,7 @@ static int team_user_linkup_option_set(struct team *team,
+
+ port->user.linkup = ctx->data.bool_val;
+ team_refresh_port_linkup(port);
++ __team_carrier_check(port->team);
+ return 0;
+ }
+
+@@ -1392,6 +1395,7 @@ static int team_user_linkup_en_option_set(struct team *team,
+
+ port->user.linkup_enabled = ctx->data.bool_val;
+ team_refresh_port_linkup(port);
++ __team_carrier_check(port->team);
+ return 0;
+ }
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 7cb105c..782e38b 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -981,6 +981,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
+ struct sk_buff *skb;
+ size_t len = total_len, align = NET_SKB_PAD, linear;
+ struct virtio_net_hdr gso = { 0 };
++ int good_linear;
+ int offset = 0;
+ int copylen;
+ bool zerocopy = false;
+@@ -1021,12 +1022,16 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
+ return -EINVAL;
+ }
+
++ good_linear = SKB_MAX_HEAD(align);
++
+ if (msg_control) {
+ /* There are 256 bytes to be copied in skb, so there is
+ * enough room for skb expand head in case it is used.
+ * The rest of the buffer is mapped from userspace.
+ */
+ copylen = gso.hdr_len ? gso.hdr_len : GOODCOPY_LEN;
++ if (copylen > good_linear)
++ copylen = good_linear;
+ linear = copylen;
+ if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS)
+ zerocopy = true;
+@@ -1034,7 +1039,10 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
+
+ if (!zerocopy) {
+ copylen = len;
+- linear = gso.hdr_len;
++ if (gso.hdr_len > good_linear)
++ linear = good_linear;
++ else
++ linear = gso.hdr_len;
+ }
+
+ skb = tun_alloc_skb(tfile, align, copylen, linear, noblock);
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 90a429b..8494bb5 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -204,9 +204,6 @@ static void intr_complete (struct urb *urb)
+ break;
+ }
+
+- if (!netif_running (dev->net))
+- return;
+-
+ status = usb_submit_urb (urb, GFP_ATOMIC);
+ if (status != 0)
+ netif_err(dev, timer, dev->net,
+diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
+index fa33b5e..e3eb952 100644
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -52,6 +52,7 @@
+ * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
+ * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
+ * RF5592 2.4G/5G 2T2R
++ * RF3070 2.4G 1T1R
+ * RF5360 2.4G 1T1R
+ * RF5370 2.4G 1T1R
+ * RF5390 2.4G 1T1R
+@@ -70,6 +71,7 @@
+ #define RF3322 0x000c
+ #define RF3053 0x000d
+ #define RF5592 0x000f
++#define RF3070 0x3070
+ #define RF3290 0x3290
+ #define RF5360 0x5360
+ #define RF5370 0x5370
+diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
+index 1400787..446eade 100644
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3152,6 +3152,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ case RF3322:
+ rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
+ break;
++ case RF3070:
+ case RF5360:
+ case RF5370:
+ case RF5372:
+@@ -3166,7 +3167,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
+ }
+
+- if (rt2x00_rf(rt2x00dev, RF3290) ||
++ if (rt2x00_rf(rt2x00dev, RF3070) ||
++ rt2x00_rf(rt2x00dev, RF3290) ||
+ rt2x00_rf(rt2x00dev, RF3322) ||
+ rt2x00_rf(rt2x00dev, RF5360) ||
+ rt2x00_rf(rt2x00dev, RF5370) ||
+@@ -4264,6 +4266,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
+ rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+ break;
+ case RF3053:
++ case RF3070:
+ case RF3290:
+ case RF5360:
+ case RF5370:
+@@ -7024,6 +7027,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
+ case RF3022:
+ case RF3052:
+ case RF3053:
++ case RF3070:
+ case RF3290:
+ case RF3320:
+ case RF3322:
+@@ -7546,6 +7550,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+ rt2x00_rf(rt2x00dev, RF2020) ||
+ rt2x00_rf(rt2x00dev, RF3021) ||
+ rt2x00_rf(rt2x00dev, RF3022) ||
++ rt2x00_rf(rt2x00dev, RF3070) ||
+ rt2x00_rf(rt2x00dev, RF3290) ||
+ rt2x00_rf(rt2x00dev, RF3320) ||
+ rt2x00_rf(rt2x00dev, RF3322) ||
+@@ -7674,6 +7679,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+ case RF3320:
+ case RF3052:
+ case RF3053:
++ case RF3070:
+ case RF3290:
+ case RF5360:
+ case RF5370:
+diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
+index 900da4b..6255850 100644
+--- a/drivers/net/xen-netback/netback.c
++++ b/drivers/net/xen-netback/netback.c
+@@ -39,6 +39,7 @@
+ #include <linux/udp.h>
+
+ #include <net/tcp.h>
++#include <net/ip6_checksum.h>
+
+ #include <xen/xen.h>
+ #include <xen/events.h>
+diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
+index ed0834e..ab69245 100644
+--- a/drivers/usb/musb/davinci.c
++++ b/drivers/usb/musb/davinci.c
+@@ -509,7 +509,7 @@ static u64 davinci_dmamask = DMA_BIT_MASK(32);
+
+ static int davinci_probe(struct platform_device *pdev)
+ {
+- struct resource musb_resources[2];
++ struct resource musb_resources[3];
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct platform_device *musb;
+ struct davinci_glue *glue;
+@@ -567,6 +567,15 @@ static int davinci_probe(struct platform_device *pdev)
+ musb_resources[1].end = pdev->resource[1].end;
+ musb_resources[1].flags = pdev->resource[1].flags;
+
++ /*
++ * For DM6467 3 resources are passed. A placeholder for the 3rd
++ * resource is always there, so it's safe to always copy it...
++ */
++ musb_resources[2].name = pdev->resource[2].name;
++ musb_resources[2].start = pdev->resource[2].start;
++ musb_resources[2].end = pdev->resource[2].end;
++ musb_resources[2].flags = pdev->resource[2].flags;
++
+ ret = platform_device_add_resources(musb, musb_resources,
+ ARRAY_SIZE(musb_resources));
+ if (ret) {
+diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
+index 6ad02f5..3dcf66f 100644
+--- a/drivers/usb/wusbcore/wa-xfer.c
++++ b/drivers/usb/wusbcore/wa-xfer.c
+@@ -91,7 +91,8 @@
+ #include "wusbhc.h"
+
+ enum {
+- WA_SEGS_MAX = 255,
++ /* [WUSB] section 8.3.3 allocates 7 bits for the segment index. */
++ WA_SEGS_MAX = 128,
+ };
+
+ enum wa_seg_status {
+@@ -446,7 +447,7 @@ static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer,
+ }
+ xfer->seg_size = (xfer->seg_size / maxpktsize) * maxpktsize;
+ xfer->segs = DIV_ROUND_UP(urb->transfer_buffer_length, xfer->seg_size);
+- if (xfer->segs >= WA_SEGS_MAX) {
++ if (xfer->segs > WA_SEGS_MAX) {
+ dev_err(dev, "BUG? ops, number of segments %d bigger than %d\n",
+ (int)(urb->transfer_buffer_length / xfer->seg_size),
+ WA_SEGS_MAX);
+diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
+index 6157f74..ec7fc87 100644
+--- a/drivers/video/kyro/fbdev.c
++++ b/drivers/video/kyro/fbdev.c
+@@ -625,15 +625,15 @@ static int kyrofb_ioctl(struct fb_info *info,
+ }
+ break;
+ case KYRO_IOCTL_UVSTRIDE:
+- if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long)))
++ if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(deviceInfo.ulOverlayUVStride)))
+ return -EFAULT;
+ break;
+ case KYRO_IOCTL_STRIDE:
+- if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long)))
++ if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(deviceInfo.ulOverlayStride)))
+ return -EFAULT;
+ break;
+ case KYRO_IOCTL_OVERLAY_OFFSET:
+- if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long)))
++ if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(deviceInfo.ulOverlayOffset)))
+ return -EFAULT;
+ break;
+ }
+diff --git a/fs/aio.c b/fs/aio.c
+index 067e3d3..6efb7f6 100644
+--- a/fs/aio.c
++++ b/fs/aio.c
+@@ -36,10 +36,10 @@
+ #include <linux/eventfd.h>
+ #include <linux/blkdev.h>
+ #include <linux/compat.h>
+-#include <linux/anon_inodes.h>
+ #include <linux/migrate.h>
+ #include <linux/ramfs.h>
+ #include <linux/percpu-refcount.h>
++#include <linux/mount.h>
+
+ #include <asm/kmap_types.h>
+ #include <asm/uaccess.h>
+@@ -80,6 +80,8 @@ struct kioctx {
+ struct percpu_ref users;
+ atomic_t dead;
+
++ struct percpu_ref reqs;
++
+ unsigned long user_id;
+
+ struct __percpu kioctx_cpu *cpu;
+@@ -107,7 +109,6 @@ struct kioctx {
+ struct page **ring_pages;
+ long nr_pages;
+
+- struct rcu_head rcu_head;
+ struct work_struct free_work;
+
+ struct {
+@@ -152,12 +153,67 @@ unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio request
+ static struct kmem_cache *kiocb_cachep;
+ static struct kmem_cache *kioctx_cachep;
+
++static struct vfsmount *aio_mnt;
++
++static const struct file_operations aio_ring_fops;
++static const struct address_space_operations aio_ctx_aops;
++
++static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages)
++{
++ struct qstr this = QSTR_INIT("[aio]", 5);
++ struct file *file;
++ struct path path;
++ struct inode *inode = alloc_anon_inode(aio_mnt->mnt_sb);
++ if (IS_ERR(inode))
++ return ERR_CAST(inode);
++
++ inode->i_mapping->a_ops = &aio_ctx_aops;
++ inode->i_mapping->private_data = ctx;
++ inode->i_size = PAGE_SIZE * nr_pages;
++
++ path.dentry = d_alloc_pseudo(aio_mnt->mnt_sb, &this);
++ if (!path.dentry) {
++ iput(inode);
++ return ERR_PTR(-ENOMEM);
++ }
++ path.mnt = mntget(aio_mnt);
++
++ d_instantiate(path.dentry, inode);
++ file = alloc_file(&path, FMODE_READ | FMODE_WRITE, &aio_ring_fops);
++ if (IS_ERR(file)) {
++ path_put(&path);
++ return file;
++ }
++
++ file->f_flags = O_RDWR;
++ file->private_data = ctx;
++ return file;
++}
++
++static struct dentry *aio_mount(struct file_system_type *fs_type,
++ int flags, const char *dev_name, void *data)
++{
++ static const struct dentry_operations ops = {
++ .d_dname = simple_dname,
++ };
++ return mount_pseudo(fs_type, "aio:", NULL, &ops, 0xa10a10a1);
++}
++
+ /* aio_setup
+ * Creates the slab caches used by the aio routines, panic on
+ * failure as this is done early during the boot sequence.
+ */
+ static int __init aio_setup(void)
+ {
++ static struct file_system_type aio_fs = {
++ .name = "aio",
++ .mount = aio_mount,
++ .kill_sb = kill_anon_super,
++ };
++ aio_mnt = kern_mount(&aio_fs);
++ if (IS_ERR(aio_mnt))
++ panic("Failed to create aio fs mount.");
++
+ kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
+ kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
+
+@@ -195,8 +251,10 @@ static void aio_free_ring(struct kioctx *ctx)
+
+ put_aio_ring_file(ctx);
+
+- if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages)
++ if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages) {
+ kfree(ctx->ring_pages);
++ ctx->ring_pages = NULL;
++ }
+ }
+
+ static int aio_ring_mmap(struct file *file, struct vm_area_struct *vma)
+@@ -283,16 +341,12 @@ static int aio_setup_ring(struct kioctx *ctx)
+ if (nr_pages < 0)
+ return -EINVAL;
+
+- file = anon_inode_getfile_private("[aio]", &aio_ring_fops, ctx, O_RDWR);
++ file = aio_private_file(ctx, nr_pages);
+ if (IS_ERR(file)) {
+ ctx->aio_ring_file = NULL;
+ return -EAGAIN;
+ }
+
+- file->f_inode->i_mapping->a_ops = &aio_ctx_aops;
+- file->f_inode->i_mapping->private_data = ctx;
+- file->f_inode->i_size = PAGE_SIZE * (loff_t)nr_pages;
+-
+ for (i = 0; i < nr_pages; i++) {
+ struct page *page;
+ page = find_or_create_page(file->f_inode->i_mapping,
+@@ -313,8 +367,10 @@ static int aio_setup_ring(struct kioctx *ctx)
+ if (nr_pages > AIO_RING_PAGES) {
+ ctx->ring_pages = kcalloc(nr_pages, sizeof(struct page *),
+ GFP_KERNEL);
+- if (!ctx->ring_pages)
++ if (!ctx->ring_pages) {
++ put_aio_ring_file(ctx);
+ return -ENOMEM;
++ }
+ }
+
+ ctx->mmap_size = nr_pages * PAGE_SIZE;
+@@ -412,26 +468,34 @@ static int kiocb_cancel(struct kioctx *ctx, struct kiocb *kiocb)
+ return cancel(kiocb);
+ }
+
+-static void free_ioctx_rcu(struct rcu_head *head)
++static void free_ioctx(struct work_struct *work)
+ {
+- struct kioctx *ctx = container_of(head, struct kioctx, rcu_head);
++ struct kioctx *ctx = container_of(work, struct kioctx, free_work);
+
++ pr_debug("freeing %p\n", ctx);
++
++ aio_free_ring(ctx);
+ free_percpu(ctx->cpu);
+ kmem_cache_free(kioctx_cachep, ctx);
+ }
+
++static void free_ioctx_reqs(struct percpu_ref *ref)
++{
++ struct kioctx *ctx = container_of(ref, struct kioctx, reqs);
++
++ INIT_WORK(&ctx->free_work, free_ioctx);
++ schedule_work(&ctx->free_work);
++}
++
+ /*
+ * When this function runs, the kioctx has been removed from the "hash table"
+ * and ctx->users has dropped to 0, so we know no more kiocbs can be submitted -
+ * now it's safe to cancel any that need to be.
+ */
+-static void free_ioctx(struct work_struct *work)
++static void free_ioctx_users(struct percpu_ref *ref)
+ {
+- struct kioctx *ctx = container_of(work, struct kioctx, free_work);
+- struct aio_ring *ring;
++ struct kioctx *ctx = container_of(ref, struct kioctx, users);
+ struct kiocb *req;
+- unsigned cpu, avail;
+- DEFINE_WAIT(wait);
+
+ spin_lock_irq(&ctx->ctx_lock);
+
+@@ -445,54 +509,8 @@ static void free_ioctx(struct work_struct *work)
+
+ spin_unlock_irq(&ctx->ctx_lock);
+
+- for_each_possible_cpu(cpu) {
+- struct kioctx_cpu *kcpu = per_cpu_ptr(ctx->cpu, cpu);
+-
+- atomic_add(kcpu->reqs_available, &ctx->reqs_available);
+- kcpu->reqs_available = 0;
+- }
+-
+- while (1) {
+- prepare_to_wait(&ctx->wait, &wait, TASK_UNINTERRUPTIBLE);
+-
+- ring = kmap_atomic(ctx->ring_pages[0]);
+- avail = (ring->head <= ring->tail)
+- ? ring->tail - ring->head
+- : ctx->nr_events - ring->head + ring->tail;
+-
+- atomic_add(avail, &ctx->reqs_available);
+- ring->head = ring->tail;
+- kunmap_atomic(ring);
+-
+- if (atomic_read(&ctx->reqs_available) >= ctx->nr_events - 1)
+- break;
+-
+- schedule();
+- }
+- finish_wait(&ctx->wait, &wait);
+-
+- WARN_ON(atomic_read(&ctx->reqs_available) > ctx->nr_events - 1);
+-
+- aio_free_ring(ctx);
+-
+- pr_debug("freeing %p\n", ctx);
+-
+- /*
+- * Here the call_rcu() is between the wait_event() for reqs_active to
+- * hit 0, and freeing the ioctx.
+- *
+- * aio_complete() decrements reqs_active, but it has to touch the ioctx
+- * after to issue a wakeup so we use rcu.
+- */
+- call_rcu(&ctx->rcu_head, free_ioctx_rcu);
+-}
+-
+-static void free_ioctx_ref(struct percpu_ref *ref)
+-{
+- struct kioctx *ctx = container_of(ref, struct kioctx, users);
+-
+- INIT_WORK(&ctx->free_work, free_ioctx);
+- schedule_work(&ctx->free_work);
++ percpu_ref_kill(&ctx->reqs);
++ percpu_ref_put(&ctx->reqs);
+ }
+
+ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
+@@ -551,6 +569,16 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
+ }
+ }
+
++static void aio_nr_sub(unsigned nr)
++{
++ spin_lock(&aio_nr_lock);
++ if (WARN_ON(aio_nr - nr > aio_nr))
++ aio_nr = 0;
++ else
++ aio_nr -= nr;
++ spin_unlock(&aio_nr_lock);
++}
++
+ /* ioctx_alloc
+ * Allocates and initializes an ioctx. Returns an ERR_PTR if it failed.
+ */
+@@ -588,8 +616,11 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
+
+ ctx->max_reqs = nr_events;
+
+- if (percpu_ref_init(&ctx->users, free_ioctx_ref))
+- goto out_freectx;
++ if (percpu_ref_init(&ctx->users, free_ioctx_users))
++ goto err;
++
++ if (percpu_ref_init(&ctx->reqs, free_ioctx_reqs))
++ goto err;
+
+ spin_lock_init(&ctx->ctx_lock);
+ spin_lock_init(&ctx->completion_lock);
+@@ -600,10 +631,10 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
+
+ ctx->cpu = alloc_percpu(struct kioctx_cpu);
+ if (!ctx->cpu)
+- goto out_freeref;
++ goto err;
+
+ if (aio_setup_ring(ctx) < 0)
+- goto out_freepcpu;
++ goto err;
+
+ atomic_set(&ctx->reqs_available, ctx->nr_events - 1);
+ ctx->req_batch = (ctx->nr_events - 1) / (num_possible_cpus() * 4);
+@@ -615,7 +646,8 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
+ if (aio_nr + nr_events > (aio_max_nr * 2UL) ||
+ aio_nr + nr_events < aio_nr) {
+ spin_unlock(&aio_nr_lock);
+- goto out_cleanup;
++ err = -EAGAIN;
++ goto err_ctx;
+ }
+ aio_nr += ctx->max_reqs;
+ spin_unlock(&aio_nr_lock);
+@@ -624,23 +656,20 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
+
+ err = ioctx_add_table(ctx, mm);
+ if (err)
+- goto out_cleanup_put;
++ goto err_cleanup;
+
+ pr_debug("allocated ioctx %p[%ld]: mm=%p mask=0x%x\n",
+ ctx, ctx->user_id, mm, ctx->nr_events);
+ return ctx;
+
+-out_cleanup_put:
+- percpu_ref_put(&ctx->users);
+-out_cleanup:
+- err = -EAGAIN;
++err_cleanup:
++ aio_nr_sub(ctx->max_reqs);
++err_ctx:
+ aio_free_ring(ctx);
+-out_freepcpu:
++err:
+ free_percpu(ctx->cpu);
+-out_freeref:
++ free_percpu(ctx->reqs.pcpu_count);
+ free_percpu(ctx->users.pcpu_count);
+-out_freectx:
+- put_aio_ring_file(ctx);
+ kmem_cache_free(kioctx_cachep, ctx);
+ pr_debug("error allocating ioctx %d\n", err);
+ return ERR_PTR(err);
+@@ -675,10 +704,7 @@ static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx)
+ * -EAGAIN with no ioctxs actually in use (as far as userspace
+ * could tell).
+ */
+- spin_lock(&aio_nr_lock);
+- BUG_ON(aio_nr - ctx->max_reqs > aio_nr);
+- aio_nr -= ctx->max_reqs;
+- spin_unlock(&aio_nr_lock);
++ aio_nr_sub(ctx->max_reqs);
+
+ if (ctx->mmap_size)
+ vm_munmap(ctx->mmap_base, ctx->mmap_size);
+@@ -810,6 +836,8 @@ static inline struct kiocb *aio_get_req(struct kioctx *ctx)
+ if (unlikely(!req))
+ goto out_put;
+
++ percpu_ref_get(&ctx->reqs);
++
+ req->ki_ctx = ctx;
+ return req;
+ out_put:
+@@ -879,12 +907,6 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
+ return;
+ }
+
+- /*
+- * Take rcu_read_lock() in case the kioctx is being destroyed, as we
+- * need to issue a wakeup after incrementing reqs_available.
+- */
+- rcu_read_lock();
+-
+ if (iocb->ki_list.next) {
+ unsigned long flags;
+
+@@ -959,7 +981,7 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
+ if (waitqueue_active(&ctx->wait))
+ wake_up(&ctx->wait);
+
+- rcu_read_unlock();
++ percpu_ref_put(&ctx->reqs);
+ }
+ EXPORT_SYMBOL(aio_complete);
+
+@@ -1370,6 +1392,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
+ return 0;
+ out_put_req:
+ put_reqs_available(ctx, 1);
++ percpu_ref_put(&ctx->reqs);
+ kiocb_free(req);
+ return ret;
+ }
+diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
+index 85c9618..22f9698 100644
+--- a/fs/anon_inodes.c
++++ b/fs/anon_inodes.c
+@@ -24,7 +24,6 @@
+
+ static struct vfsmount *anon_inode_mnt __read_mostly;
+ static struct inode *anon_inode_inode;
+-static const struct file_operations anon_inode_fops;
+
+ /*
+ * anon_inodefs_dname() is called from d_path().
+@@ -39,51 +38,6 @@ static const struct dentry_operations anon_inodefs_dentry_operations = {
+ .d_dname = anon_inodefs_dname,
+ };
+
+-/*
+- * nop .set_page_dirty method so that people can use .page_mkwrite on
+- * anon inodes.
+- */
+-static int anon_set_page_dirty(struct page *page)
+-{
+- return 0;
+-};
+-
+-static const struct address_space_operations anon_aops = {
+- .set_page_dirty = anon_set_page_dirty,
+-};
+-
+-/*
+- * A single inode exists for all anon_inode files. Contrary to pipes,
+- * anon_inode inodes have no associated per-instance data, so we need
+- * only allocate one of them.
+- */
+-static struct inode *anon_inode_mkinode(struct super_block *s)
+-{
+- struct inode *inode = new_inode_pseudo(s);
+-
+- if (!inode)
+- return ERR_PTR(-ENOMEM);
+-
+- inode->i_ino = get_next_ino();
+- inode->i_fop = &anon_inode_fops;
+-
+- inode->i_mapping->a_ops = &anon_aops;
+-
+- /*
+- * Mark the inode dirty from the very beginning,
+- * that way it will never be moved to the dirty
+- * list because mark_inode_dirty() will think
+- * that it already _is_ on the dirty list.
+- */
+- inode->i_state = I_DIRTY;
+- inode->i_mode = S_IRUSR | S_IWUSR;
+- inode->i_uid = current_fsuid();
+- inode->i_gid = current_fsgid();
+- inode->i_flags |= S_PRIVATE;
+- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+- return inode;
+-}
+-
+ static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data)
+ {
+@@ -92,7 +46,7 @@ static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
+ &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
+ if (!IS_ERR(root)) {
+ struct super_block *s = root->d_sb;
+- anon_inode_inode = anon_inode_mkinode(s);
++ anon_inode_inode = alloc_anon_inode(s);
+ if (IS_ERR(anon_inode_inode)) {
+ dput(root);
+ deactivate_locked_super(s);
+@@ -134,7 +88,7 @@ struct file *anon_inode_getfile_private(const char *name,
+ if (fops->owner && !try_module_get(fops->owner))
+ return ERR_PTR(-ENOENT);
+
+- inode = anon_inode_mkinode(anon_inode_mnt->mnt_sb);
++ inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
+ if (IS_ERR(inode)) {
+ file = ERR_PTR(-ENOMEM);
+ goto err_module;
+diff --git a/fs/libfs.c b/fs/libfs.c
+index 3a3a9b5..193e0c2 100644
+--- a/fs/libfs.c
++++ b/fs/libfs.c
+@@ -993,3 +993,46 @@ EXPORT_SYMBOL_GPL(simple_attr_open);
+ EXPORT_SYMBOL_GPL(simple_attr_release);
+ EXPORT_SYMBOL_GPL(simple_attr_read);
+ EXPORT_SYMBOL_GPL(simple_attr_write);
++
++/*
++ * nop .set_page_dirty method so that people can use .page_mkwrite on
++ * anon inodes.
++ */
++static int anon_set_page_dirty(struct page *page)
++{
++ return 0;
++};
++
++/*
++ * A single inode exists for all anon_inode files. Contrary to pipes,
++ * anon_inode inodes have no associated per-instance data, so we need
++ * only allocate one of them.
++ */
++struct inode *alloc_anon_inode(struct super_block *s)
++{
++ static const struct address_space_operations anon_aops = {
++ .set_page_dirty = anon_set_page_dirty,
++ };
++ struct inode *inode = new_inode_pseudo(s);
++
++ if (!inode)
++ return ERR_PTR(-ENOMEM);
++
++ inode->i_ino = get_next_ino();
++ inode->i_mapping->a_ops = &anon_aops;
++
++ /*
++ * Mark the inode dirty from the very beginning,
++ * that way it will never be moved to the dirty
++ * list because mark_inode_dirty() will think
++ * that it already _is_ on the dirty list.
++ */
++ inode->i_state = I_DIRTY;
++ inode->i_mode = S_IRUSR | S_IWUSR;
++ inode->i_uid = current_fsuid();
++ inode->i_gid = current_fsgid();
++ inode->i_flags |= S_PRIVATE;
++ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
++ return inode;
++}
++EXPORT_SYMBOL(alloc_anon_inode);
+diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
+index 668e8f4..2e1e6c3 100644
+--- a/fs/xfs/xfs_ioctl.c
++++ b/fs/xfs/xfs_ioctl.c
+@@ -1717,6 +1717,12 @@ xfs_file_ioctl(
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
+ return -XFS_ERROR(EROFS);
+
++ if (!capable(CAP_SYS_ADMIN))
++ return -EPERM;
++
++ if (mp->m_flags & XFS_MOUNT_RDONLY)
++ return -XFS_ERROR(EROFS);
++
+ if (copy_from_user(&eofb, arg, sizeof(eofb)))
+ return -XFS_ERROR(EFAULT);
+
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 3f40547..fefa7b0 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2562,6 +2562,7 @@ extern int simple_write_begin(struct file *file, struct address_space *mapping,
+ extern int simple_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata);
++extern struct inode *alloc_anon_inode(struct super_block *);
+
+ extern struct dentry *simple_lookup(struct inode *, struct dentry *, unsigned int flags);
+ extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
+diff --git a/include/linux/net.h b/include/linux/net.h
+index 4f27575..8bd9d92 100644
+--- a/include/linux/net.h
++++ b/include/linux/net.h
+@@ -163,6 +163,14 @@ struct proto_ops {
+ #endif
+ int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
+ struct msghdr *m, size_t total_len);
++ /* Notes for implementing recvmsg:
++ * ===============================
++ * msg->msg_namelen should get updated by the recvmsg handlers
++ * iff msg_name != NULL. It is by default 0 to prevent
++ * returning uninitialized memory to user space. The recvfrom
++ * handlers can assume that msg.msg_name is either NULL or has
++ * a minimum size of sizeof(struct sockaddr_storage).
++ */
+ int (*recvmsg) (struct kiocb *iocb, struct socket *sock,
+ struct msghdr *m, size_t total_len,
+ int flags);
+diff --git a/include/linux/random.h b/include/linux/random.h
+index 6312dd9..bf9085e 100644
+--- a/include/linux/random.h
++++ b/include/linux/random.h
+@@ -50,9 +50,9 @@ static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
+ {
+ u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
+
+- state->s1 = __seed(i, 1);
+- state->s2 = __seed(i, 7);
+- state->s3 = __seed(i, 15);
++ state->s1 = __seed(i, 2);
++ state->s2 = __seed(i, 8);
++ state->s3 = __seed(i, 16);
+ }
+
+ #ifdef CONFIG_ARCH_RANDOM
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index c2d8933..f66f346 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -333,11 +333,6 @@ typedef unsigned int sk_buff_data_t;
+ typedef unsigned char *sk_buff_data_t;
+ #endif
+
+-#if defined(CONFIG_NF_DEFRAG_IPV4) || defined(CONFIG_NF_DEFRAG_IPV4_MODULE) || \
+- defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
+-#define NET_SKBUFF_NF_DEFRAG_NEEDED 1
+-#endif
+-
+ /**
+ * struct sk_buff - socket buffer
+ * @next: Next buffer in list
+@@ -370,7 +365,6 @@ typedef unsigned char *sk_buff_data_t;
+ * @protocol: Packet protocol from driver
+ * @destructor: Destruct function
+ * @nfct: Associated connection, if any
+- * @nfct_reasm: netfilter conntrack re-assembly pointer
+ * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
+ * @skb_iif: ifindex of device we arrived on
+ * @tc_index: Traffic control index
+@@ -459,9 +453,6 @@ struct sk_buff {
+ #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ struct nf_conntrack *nfct;
+ #endif
+-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
+- struct sk_buff *nfct_reasm;
+-#endif
+ #ifdef CONFIG_BRIDGE_NETFILTER
+ struct nf_bridge_info *nf_bridge;
+ #endif
+@@ -2605,18 +2596,6 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct)
+ atomic_inc(&nfct->use);
+ }
+ #endif
+-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
+-static inline void nf_conntrack_get_reasm(struct sk_buff *skb)
+-{
+- if (skb)
+- atomic_inc(&skb->users);
+-}
+-static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
+-{
+- if (skb)
+- kfree_skb(skb);
+-}
+-#endif
+ #ifdef CONFIG_BRIDGE_NETFILTER
+ static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
+ {
+@@ -2635,10 +2614,6 @@ static inline void nf_reset(struct sk_buff *skb)
+ nf_conntrack_put(skb->nfct);
+ skb->nfct = NULL;
+ #endif
+-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
+- nf_conntrack_put_reasm(skb->nfct_reasm);
+- skb->nfct_reasm = NULL;
+-#endif
+ #ifdef CONFIG_BRIDGE_NETFILTER
+ nf_bridge_put(skb->nf_bridge);
+ skb->nf_bridge = NULL;
+@@ -2660,10 +2635,6 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src)
+ nf_conntrack_get(src->nfct);
+ dst->nfctinfo = src->nfctinfo;
+ #endif
+-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
+- dst->nfct_reasm = src->nfct_reasm;
+- nf_conntrack_get_reasm(src->nfct_reasm);
+-#endif
+ #ifdef CONFIG_BRIDGE_NETFILTER
+ dst->nf_bridge = src->nf_bridge;
+ nf_bridge_get(src->nf_bridge);
+@@ -2675,9 +2646,6 @@ static inline void nf_copy(struct sk_buff *dst, const struct sk_buff *src)
+ #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ nf_conntrack_put(dst->nfct);
+ #endif
+-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
+- nf_conntrack_put_reasm(dst->nfct_reasm);
+-#endif
+ #ifdef CONFIG_BRIDGE_NETFILTER
+ nf_bridge_put(dst->nf_bridge);
+ #endif
+diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
+index 1855f0a..c557c6d 100644
+--- a/include/linux/vm_event_item.h
++++ b/include/linux/vm_event_item.h
+@@ -39,6 +39,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
+ PAGEOUTRUN, ALLOCSTALL, PGROTATED,
+ #ifdef CONFIG_NUMA_BALANCING
+ NUMA_PTE_UPDATES,
++ NUMA_HUGE_PTE_UPDATES,
+ NUMA_HINT_FAULTS,
+ NUMA_HINT_FAULTS_LOCAL,
+ NUMA_PAGE_MIGRATE,
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 5e52688..301f10c 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -464,7 +464,7 @@ extern int compat_ip_getsockopt(struct sock *sk, int level,
+ int optname, char __user *optval, int __user *optlen);
+ extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));
+
+-extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len);
++extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len);
+ extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
+ __be16 port, u32 info, u8 *payload);
+ extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
+diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
+index 9c4d37e..772252d 100644
+--- a/include/net/ip_vs.h
++++ b/include/net/ip_vs.h
+@@ -109,7 +109,6 @@ extern int ip_vs_conn_tab_size;
+ struct ip_vs_iphdr {
+ __u32 len; /* IPv4 simply where L4 starts
+ IPv6 where L4 Transport Header starts */
+- __u32 thoff_reasm; /* Transport Header Offset in nfct_reasm skb */
+ __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/
+ __s16 protocol;
+ __s32 flags;
+@@ -117,34 +116,12 @@ struct ip_vs_iphdr {
+ union nf_inet_addr daddr;
+ };
+
+-/* Dependency to module: nf_defrag_ipv6 */
+-#if defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
+-static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
+-{
+- return skb->nfct_reasm;
+-}
+-static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
+- int len, void *buffer,
+- const struct ip_vs_iphdr *ipvsh)
+-{
+- if (unlikely(ipvsh->fragoffs && skb_nfct_reasm(skb)))
+- return skb_header_pointer(skb_nfct_reasm(skb),
+- ipvsh->thoff_reasm, len, buffer);
+-
+- return skb_header_pointer(skb, offset, len, buffer);
+-}
+-#else
+-static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
+-{
+- return NULL;
+-}
+ static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
+ int len, void *buffer,
+ const struct ip_vs_iphdr *ipvsh)
+ {
+ return skb_header_pointer(skb, offset, len, buffer);
+ }
+-#endif
+
+ static inline void
+ ip_vs_fill_ip4hdr(const void *nh, struct ip_vs_iphdr *iphdr)
+@@ -171,19 +148,12 @@ ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr)
+ (struct ipv6hdr *)skb_network_header(skb);
+ iphdr->saddr.in6 = iph->saddr;
+ iphdr->daddr.in6 = iph->daddr;
+- /* ipv6_find_hdr() updates len, flags, thoff_reasm */
+- iphdr->thoff_reasm = 0;
++ /* ipv6_find_hdr() updates len, flags */
+ iphdr->len = 0;
+ iphdr->flags = 0;
+ iphdr->protocol = ipv6_find_hdr(skb, &iphdr->len, -1,
+ &iphdr->fragoffs,
+ &iphdr->flags);
+- /* get proto from re-assembled packet and it's offset */
+- if (skb_nfct_reasm(skb))
+- iphdr->protocol = ipv6_find_hdr(skb_nfct_reasm(skb),
+- &iphdr->thoff_reasm,
+- -1, NULL, NULL);
+-
+ } else
+ #endif
+ {
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index bbf1c8f..1f96efd 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -802,8 +802,10 @@ extern int compat_ipv6_getsockopt(struct sock *sk,
+ extern int ip6_datagram_connect(struct sock *sk,
+ struct sockaddr *addr, int addr_len);
+
+-extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
+-extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);
++extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
++ int *addr_len);
++extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
++ int *addr_len);
+ extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
+ u32 info, u8 *payload);
+ extern void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
+diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
+index fd79c9a..17920d8 100644
+--- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h
++++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
+@@ -6,10 +6,7 @@ extern void nf_defrag_ipv6_enable(void);
+ extern int nf_ct_frag6_init(void);
+ extern void nf_ct_frag6_cleanup(void);
+ extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
+-extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
+- struct net_device *in,
+- struct net_device *out,
+- int (*okfn)(struct sk_buff *));
++extern void nf_ct_frag6_consume_orig(struct sk_buff *skb);
+
+ struct inet_frags_ctl;
+
+diff --git a/include/net/ping.h b/include/net/ping.h
+index 5db0224..2b496e9 100644
+--- a/include/net/ping.h
++++ b/include/net/ping.h
+@@ -31,7 +31,8 @@
+
+ /* Compatibility glue so we can support IPv6 when it's compiled as a module */
+ struct pingv6_ops {
+- int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len);
++ int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len,
++ int *addr_len);
+ int (*ip6_datagram_recv_ctl)(struct sock *sk, struct msghdr *msg,
+ struct sk_buff *skb);
+ int (*icmpv6_err_convert)(u8 type, u8 code, int *err);
+diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
+index 9b82913..66f925d 100644
+--- a/include/uapi/linux/pkt_sched.h
++++ b/include/uapi/linux/pkt_sched.h
+@@ -759,13 +759,14 @@ enum {
+
+ TCA_FQ_RATE_ENABLE, /* enable/disable rate limiting */
+
+- TCA_FQ_FLOW_DEFAULT_RATE,/* for sockets with unspecified sk_rate,
+- * use the following rate
+- */
++ TCA_FQ_FLOW_DEFAULT_RATE,/* obsolete, do not use */
+
+ TCA_FQ_FLOW_MAX_RATE, /* per flow max rate */
+
+ TCA_FQ_BUCKETS_LOG, /* log2(number of buckets) */
++
++ TCA_FQ_FLOW_REFILL_DELAY, /* flow credit refill delay in usec */
++
+ __TCA_FQ_MAX
+ };
+
+diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
+index bb22151..af8d1d4 100644
+--- a/kernel/time/ntp.c
++++ b/kernel/time/ntp.c
+@@ -475,6 +475,7 @@ static void sync_cmos_clock(struct work_struct *work)
+ * called as close as possible to 500 ms before the new second starts.
+ * This code is run on a timer. If the clock is set, that timer
+ * may not expire at the correct time. Thus, we adjust...
++ * We want the clock to be within a couple of ticks from the target.
+ */
+ if (!ntp_synced()) {
+ /*
+@@ -485,7 +486,7 @@ static void sync_cmos_clock(struct work_struct *work)
+ }
+
+ getnstimeofday(&now);
+- if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) {
++ if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec * 5) {
+ struct timespec adjust = now;
+
+ fail = -ENODEV;
+diff --git a/lib/random32.c b/lib/random32.c
+index 52280d5..01e8890 100644
+--- a/lib/random32.c
++++ b/lib/random32.c
+@@ -141,7 +141,7 @@ void prandom_seed(u32 entropy)
+ */
+ for_each_possible_cpu (i) {
+ struct rnd_state *state = &per_cpu(net_rand_state, i);
+- state->s1 = __seed(state->s1 ^ entropy, 1);
++ state->s1 = __seed(state->s1 ^ entropy, 2);
+ }
+ }
+ EXPORT_SYMBOL(prandom_seed);
+@@ -158,9 +158,9 @@ static int __init prandom_init(void)
+ struct rnd_state *state = &per_cpu(net_rand_state,i);
+
+ #define LCG(x) ((x) * 69069) /* super-duper LCG */
+- state->s1 = __seed(LCG(i + jiffies), 1);
+- state->s2 = __seed(LCG(state->s1), 7);
+- state->s3 = __seed(LCG(state->s2), 15);
++ state->s1 = __seed(LCG(i + jiffies), 2);
++ state->s2 = __seed(LCG(state->s1), 8);
++ state->s3 = __seed(LCG(state->s2), 16);
+
+ /* "warm it up" */
+ prandom_u32_state(state);
+@@ -187,9 +187,9 @@ static int __init prandom_reseed(void)
+ u32 seeds[3];
+
+ get_random_bytes(&seeds, sizeof(seeds));
+- state->s1 = __seed(seeds[0], 1);
+- state->s2 = __seed(seeds[1], 7);
+- state->s3 = __seed(seeds[2], 15);
++ state->s1 = __seed(seeds[0], 2);
++ state->s2 = __seed(seeds[1], 8);
++ state->s3 = __seed(seeds[2], 16);
+
+ /* mix it in */
+ prandom_u32_state(state);
+diff --git a/mm/mprotect.c b/mm/mprotect.c
+index 412ba2b..6c3f56f 100644
+--- a/mm/mprotect.c
++++ b/mm/mprotect.c
+@@ -138,6 +138,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
+ pmd_t *pmd;
+ unsigned long next;
+ unsigned long pages = 0;
++ unsigned long nr_huge_updates = 0;
+ bool all_same_node;
+
+ pmd = pmd_offset(pud, addr);
+@@ -148,7 +149,8 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
+ split_huge_page_pmd(vma, addr, pmd);
+ else if (change_huge_pmd(vma, pmd, addr, newprot,
+ prot_numa)) {
+- pages++;
++ pages += HPAGE_PMD_NR;
++ nr_huge_updates++;
+ continue;
+ }
+ /* fall through */
+@@ -168,6 +170,9 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
+ change_pmd_protnuma(vma->vm_mm, addr, pmd);
+ } while (pmd++, addr = next, addr != end);
+
++ if (nr_huge_updates)
++ count_vm_numa_events(NUMA_HUGE_PTE_UPDATES, nr_huge_updates);
++
+ return pages;
+ }
+
+diff --git a/mm/vmstat.c b/mm/vmstat.c
+index 9bb3145..5a442a7 100644
+--- a/mm/vmstat.c
++++ b/mm/vmstat.c
+@@ -812,6 +812,7 @@ const char * const vmstat_text[] = {
+
+ #ifdef CONFIG_NUMA_BALANCING
+ "numa_pte_updates",
++ "numa_huge_pte_updates",
+ "numa_hint_faults",
+ "numa_hint_faults_local",
+ "numa_pages_migrated",
+diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
+index 7fee50d..7d424ac 100644
+--- a/net/appletalk/ddp.c
++++ b/net/appletalk/ddp.c
+@@ -1735,7 +1735,6 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
+ size_t size, int flags)
+ {
+ struct sock *sk = sock->sk;
+- struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
+ struct ddpehdr *ddp;
+ int copied = 0;
+ int offset = 0;
+@@ -1764,14 +1763,13 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
+ }
+ err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
+
+- if (!err) {
+- if (sat) {
+- sat->sat_family = AF_APPLETALK;
+- sat->sat_port = ddp->deh_sport;
+- sat->sat_addr.s_node = ddp->deh_snode;
+- sat->sat_addr.s_net = ddp->deh_snet;
+- }
+- msg->msg_namelen = sizeof(*sat);
++ if (!err && msg->msg_name) {
++ struct sockaddr_at *sat = msg->msg_name;
++ sat->sat_family = AF_APPLETALK;
++ sat->sat_port = ddp->deh_sport;
++ sat->sat_addr.s_node = ddp->deh_snode;
++ sat->sat_addr.s_net = ddp->deh_snet;
++ msg->msg_namelen = sizeof(*sat);
+ }
+
+ skb_free_datagram(sk, skb); /* Free the datagram. */
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 737bef5..7b49100 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -531,8 +531,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+ struct sk_buff *skb;
+ int copied, error = -EINVAL;
+
+- msg->msg_namelen = 0;
+-
+ if (sock->state != SS_CONNECTED)
+ return -ENOTCONN;
+
+diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
+index 4b4d2b7..78c474f 100644
+--- a/net/ax25/af_ax25.c
++++ b/net/ax25/af_ax25.c
+@@ -1636,11 +1636,11 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
+
+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+
+- if (msg->msg_namelen != 0) {
+- struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name;
++ if (msg->msg_name) {
+ ax25_digi digi;
+ ax25_address src;
+ const unsigned char *mac = skb_mac_header(skb);
++ struct sockaddr_ax25 *sax = msg->msg_name;
+
+ memset(sax, 0, sizeof(struct full_sockaddr_ax25));
+ ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
+diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
+index 9096137..6629cdc 100644
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -221,8 +221,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (flags & (MSG_OOB))
+ return -EOPNOTSUPP;
+
+- msg->msg_namelen = 0;
+-
+ skb = skb_recv_datagram(sk, flags, noblock, &err);
+ if (!skb) {
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+@@ -287,8 +285,6 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+- msg->msg_namelen = 0;
+-
+ BT_DBG("sk %p size %zu", sk, size);
+
+ lock_sock(sk);
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index 9bd7d95..fa4bf66 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -752,8 +752,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (!skb)
+ return err;
+
+- msg->msg_namelen = 0;
+-
+ copied = skb->len;
+ if (len < copied) {
+ msg->msg_flags |= MSG_TRUNC;
+diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
+index 30b3721..c1c6028 100644
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -608,7 +608,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+
+ if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
+ rfcomm_dlc_accept(d);
+- msg->msg_namelen = 0;
+ return 0;
+ }
+
+diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
+index 96bd388..d021e44 100644
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -715,7 +715,6 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+ test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
+ sco_conn_defer_accept(pi->conn->hcon, pi->setting);
+ sk->sk_state = BT_CONFIG;
+- msg->msg_namelen = 0;
+
+ release_sock(sk);
+ return 0;
+diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
+index c41d5fb..547504c 100644
+--- a/net/bridge/br_if.c
++++ b/net/bridge/br_if.c
+@@ -172,6 +172,8 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)
+ del_nbp(p);
+ }
+
++ br_fdb_delete_by_port(br, NULL, 1);
++
+ del_timer_sync(&br->gc_timer);
+
+ br_sysfs_delbr(br->dev);
+diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
+index 05a41c7..d6be3ed 100644
+--- a/net/caif/caif_socket.c
++++ b/net/caif/caif_socket.c
+@@ -286,8 +286,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (m->msg_flags&MSG_OOB)
+ goto read_error;
+
+- m->msg_namelen = 0;
+-
+ skb = skb_recv_datagram(sk, flags, 0 , &ret);
+ if (!skb)
+ goto read_error;
+@@ -361,8 +359,6 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (flags&MSG_OOB)
+ goto out;
+
+- msg->msg_namelen = 0;
+-
+ /*
+ * Lock the socket to prevent queue disordering
+ * while sleeps in memcpy_tomsg
+diff --git a/net/compat.c b/net/compat.c
+index 8903258..dd32e34 100644
+--- a/net/compat.c
++++ b/net/compat.c
+@@ -72,7 +72,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
+ __get_user(kmsg->msg_flags, &umsg->msg_flags))
+ return -EFAULT;
+ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
+- return -EINVAL;
++ kmsg->msg_namelen = sizeof(struct sockaddr_storage);
+ kmsg->msg_name = compat_ptr(tmp1);
+ kmsg->msg_iov = compat_ptr(tmp2);
+ kmsg->msg_control = compat_ptr(tmp3);
+@@ -93,7 +93,8 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
+ if (err < 0)
+ return err;
+ }
+- kern_msg->msg_name = kern_address;
++ if (kern_msg->msg_name)
++ kern_msg->msg_name = kern_address;
+ } else
+ kern_msg->msg_name = NULL;
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 3430b1e..3d13874 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -1691,13 +1691,9 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
+ kfree_skb(skb);
+ return NET_RX_DROP;
+ }
+- skb->protocol = eth_type_trans(skb, dev);
+
+- /* eth_type_trans() can set pkt_type.
+- * call skb_scrub_packet() after it to clear pkt_type _after_ calling
+- * eth_type_trans().
+- */
+ skb_scrub_packet(skb, true);
++ skb->protocol = eth_type_trans(skb, dev);
+
+ return netif_rx(skb);
+ }
+@@ -4819,7 +4815,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags)
+ {
+ const struct net_device_ops *ops = dev->netdev_ops;
+
+- if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags)
++ if (ops->ndo_change_rx_flags)
+ ops->ndo_change_rx_flags(dev, flags);
+ }
+
+diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
+index 2e65413..f409e0b 100644
+--- a/net/core/fib_rules.c
++++ b/net/core/fib_rules.c
+@@ -460,7 +460,8 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh)
+ if (frh->action && (frh->action != rule->action))
+ continue;
+
+- if (frh->table && (frh_get_table(frh, tb) != rule->table))
++ if (frh_get_table(frh, tb) &&
++ (frh_get_table(frh, tb) != rule->table))
+ continue;
+
+ if (tb[FRA_PRIORITY] &&
+diff --git a/net/core/iovec.c b/net/core/iovec.c
+index b77eeec..7d84ea1 100644
+--- a/net/core/iovec.c
++++ b/net/core/iovec.c
+@@ -48,7 +48,8 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a
+ if (err < 0)
+ return err;
+ }
+- m->msg_name = address;
++ if (m->msg_name)
++ m->msg_name = address;
+ } else {
+ m->msg_name = NULL;
+ }
+diff --git a/net/core/pktgen.c b/net/core/pktgen.c
+index 261357a..a797fff 100644
+--- a/net/core/pktgen.c
++++ b/net/core/pktgen.c
+@@ -2527,6 +2527,8 @@ static int process_ipsec(struct pktgen_dev *pkt_dev,
+ if (x) {
+ int ret;
+ __u8 *eth;
++ struct iphdr *iph;
++
+ nhead = x->props.header_len - skb_headroom(skb);
+ if (nhead > 0) {
+ ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
+@@ -2548,6 +2550,11 @@ static int process_ipsec(struct pktgen_dev *pkt_dev,
+ eth = (__u8 *) skb_push(skb, ETH_HLEN);
+ memcpy(eth, pkt_dev->hh, 12);
+ *(u16 *) &eth[12] = protocol;
++
++ /* Update IPv4 header len as well as checksum value */
++ iph = ip_hdr(skb);
++ iph->tot_len = htons(skb->len - ETH_HLEN);
++ ip_send_check(iph);
+ }
+ }
+ return 1;
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index d81cff1..c28c7fe 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -580,9 +580,6 @@ static void skb_release_head_state(struct sk_buff *skb)
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK)
+ nf_conntrack_put(skb->nfct);
+ #endif
+-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
+- nf_conntrack_put_reasm(skb->nfct_reasm);
+-#endif
+ #ifdef CONFIG_BRIDGE_NETFILTER
+ nf_bridge_put(skb->nf_bridge);
+ #endif
+@@ -2758,6 +2755,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
+ struct sk_buff *segs = NULL;
+ struct sk_buff *tail = NULL;
+ struct sk_buff *fskb = skb_shinfo(skb)->frag_list;
++ skb_frag_t *skb_frag = skb_shinfo(skb)->frags;
+ unsigned int mss = skb_shinfo(skb)->gso_size;
+ unsigned int doffset = skb->data - skb_mac_header(skb);
+ unsigned int offset = doffset;
+@@ -2797,16 +2795,38 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
+ if (hsize > len || !sg)
+ hsize = len;
+
+- if (!hsize && i >= nfrags) {
+- BUG_ON(fskb->len != len);
++ if (!hsize && i >= nfrags && skb_headlen(fskb) &&
++ (skb_headlen(fskb) == len || sg)) {
++ BUG_ON(skb_headlen(fskb) > len);
++
++ i = 0;
++ nfrags = skb_shinfo(fskb)->nr_frags;
++ skb_frag = skb_shinfo(fskb)->frags;
++ pos += skb_headlen(fskb);
++
++ while (pos < offset + len) {
++ BUG_ON(i >= nfrags);
++
++ size = skb_frag_size(skb_frag);
++ if (pos + size > offset + len)
++ break;
++
++ i++;
++ pos += size;
++ skb_frag++;
++ }
+
+- pos += len;
+ nskb = skb_clone(fskb, GFP_ATOMIC);
+ fskb = fskb->next;
+
+ if (unlikely(!nskb))
+ goto err;
+
++ if (unlikely(pskb_trim(nskb, len))) {
++ kfree_skb(nskb);
++ goto err;
++ }
++
+ hsize = skb_end_offset(nskb);
+ if (skb_cow_head(nskb, doffset + headroom)) {
+ kfree_skb(nskb);
+@@ -2850,7 +2870,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
+ nskb->data - tnl_hlen,
+ doffset + tnl_hlen);
+
+- if (fskb != skb_shinfo(skb)->frag_list)
++ if (nskb->len == len + doffset)
+ goto perform_csum_check;
+
+ if (!sg) {
+@@ -2868,8 +2888,28 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
+
+ skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;
+
+- while (pos < offset + len && i < nfrags) {
+- *frag = skb_shinfo(skb)->frags[i];
++ while (pos < offset + len) {
++ if (i >= nfrags) {
++ BUG_ON(skb_headlen(fskb));
++
++ i = 0;
++ nfrags = skb_shinfo(fskb)->nr_frags;
++ skb_frag = skb_shinfo(fskb)->frags;
++
++ BUG_ON(!nfrags);
++
++ fskb = fskb->next;
++ }
++
++ if (unlikely(skb_shinfo(nskb)->nr_frags >=
++ MAX_SKB_FRAGS)) {
++ net_warn_ratelimited(
++ "skb_segment: too many frags: %u %u\n",
++ pos, mss);
++ goto err;
++ }
++
++ *frag = *skb_frag;
+ __skb_frag_ref(frag);
+ size = skb_frag_size(frag);
+
+@@ -2882,6 +2922,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
+
+ if (pos + size <= offset + len) {
+ i++;
++ skb_frag++;
+ pos += size;
+ } else {
+ skb_frag_size_sub(frag, pos + size - (offset + len));
+@@ -2891,25 +2932,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
+ frag++;
+ }
+
+- if (pos < offset + len) {
+- struct sk_buff *fskb2 = fskb;
+-
+- BUG_ON(pos + fskb->len != offset + len);
+-
+- pos += fskb->len;
+- fskb = fskb->next;
+-
+- if (fskb2->next) {
+- fskb2 = skb_clone(fskb2, GFP_ATOMIC);
+- if (!fskb2)
+- goto err;
+- } else
+- skb_get(fskb2);
+-
+- SKB_FRAG_ASSERT(nskb);
+- skb_shinfo(nskb)->frag_list = fskb2;
+- }
+-
+ skip_fraglist:
+ nskb->data_len = len - hsize;
+ nskb->len += nskb->data_len;
+diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
+index ff41b4d..008f337 100644
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -957,7 +957,7 @@ lowpan_process_data(struct sk_buff *skb)
+ * Traffic class carried in-line
+ * ECN + DSCP (1 byte), Flow Label is elided
+ */
+- case 1: /* 10b */
++ case 2: /* 10b */
+ if (lowpan_fetch_skb_u8(skb, &tmp))
+ goto drop;
+
+@@ -968,7 +968,7 @@ lowpan_process_data(struct sk_buff *skb)
+ * Flow Label carried in-line
+ * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided
+ */
+- case 2: /* 01b */
++ case 1: /* 01b */
+ if (lowpan_fetch_skb_u8(skb, &tmp))
+ goto drop;
+
+diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
+index 581a595..1865fdf 100644
+--- a/net/ieee802154/dgram.c
++++ b/net/ieee802154/dgram.c
+@@ -315,9 +315,8 @@ static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk,
+ if (saddr) {
+ saddr->family = AF_IEEE802154;
+ saddr->addr = mac_cb(skb)->sa;
+- }
+- if (addr_len)
+ *addr_len = sizeof(*saddr);
++ }
+
+ if (flags & MSG_TRUNC)
+ copied = skb->len;
+diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
+index b28e863..19e3637 100644
+--- a/net/ipv4/datagram.c
++++ b/net/ipv4/datagram.c
+@@ -57,7 +57,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+ if (IS_ERR(rt)) {
+ err = PTR_ERR(rt);
+ if (err == -ENETUNREACH)
+- IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
++ IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
+ goto out;
+ }
+
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
+index d9c4f11..23e6ab0 100644
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -368,7 +368,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf
+ /*
+ * Handle MSG_ERRQUEUE
+ */
+-int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
++int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
+ {
+ struct sock_exterr_skb *serr;
+ struct sk_buff *skb, *skb2;
+@@ -405,6 +405,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
+ serr->addr_offset);
+ sin->sin_port = serr->port;
+ memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
++ *addr_len = sizeof(*sin);
+ }
+
+ memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
+diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
+index 63a6d6d..254f11c 100644
+--- a/net/ipv4/ip_tunnel.c
++++ b/net/ipv4/ip_tunnel.c
+@@ -454,6 +454,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
+ tstats->rx_bytes += skb->len;
+ u64_stats_update_end(&tstats->syncp);
+
++ skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
++
+ if (tunnel->dev->type == ARPHRD_ETHER) {
+ skb->protocol = eth_type_trans(skb, tunnel->dev);
+ skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
+@@ -461,8 +463,6 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
+ skb->dev = tunnel->dev;
+ }
+
+- skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
+-
+ gro_cells_receive(&tunnel->gro_cells, skb);
+ return 0;
+
+diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
+index 6e87f85..26847e1 100644
+--- a/net/ipv4/ip_vti.c
++++ b/net/ipv4/ip_vti.c
+@@ -190,6 +190,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
+ if (!rt->dst.xfrm ||
+ rt->dst.xfrm->props.mode != XFRM_MODE_TUNNEL) {
+ dev->stats.tx_carrier_errors++;
++ ip_rt_put(rt);
+ goto tx_error_icmp;
+ }
+ tdev = rt->dst.dev;
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index d7d9882..c482f7c 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -769,7 +769,7 @@ int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ err = PTR_ERR(rt);
+ rt = NULL;
+ if (err == -ENETUNREACH)
+- IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
++ IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
+ goto out;
+ }
+
+@@ -827,8 +827,6 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ {
+ struct inet_sock *isk = inet_sk(sk);
+ int family = sk->sk_family;
+- struct sockaddr_in *sin;
+- struct sockaddr_in6 *sin6;
+ struct sk_buff *skb;
+ int copied, err;
+
+@@ -838,19 +836,13 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ if (flags & MSG_OOB)
+ goto out;
+
+- if (addr_len) {
+- if (family == AF_INET)
+- *addr_len = sizeof(*sin);
+- else if (family == AF_INET6 && addr_len)
+- *addr_len = sizeof(*sin6);
+- }
+-
+ if (flags & MSG_ERRQUEUE) {
+ if (family == AF_INET) {
+- return ip_recv_error(sk, msg, len);
++ return ip_recv_error(sk, msg, len, addr_len);
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (family == AF_INET6) {
+- return pingv6_ops.ipv6_recv_error(sk, msg, len);
++ return pingv6_ops.ipv6_recv_error(sk, msg, len,
++ addr_len);
+ #endif
+ }
+ }
+@@ -874,11 +866,15 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+
+ /* Copy the address and add cmsg data. */
+ if (family == AF_INET) {
+- sin = (struct sockaddr_in *) msg->msg_name;
+- sin->sin_family = AF_INET;
+- sin->sin_port = 0 /* skb->h.uh->source */;
+- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+- memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
++ struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
++
++ if (sin) {
++ sin->sin_family = AF_INET;
++ sin->sin_port = 0 /* skb->h.uh->source */;
++ sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
++ memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
++ *addr_len = sizeof(*sin);
++ }
+
+ if (isk->cmsg_flags)
+ ip_cmsg_recv(msg, skb);
+@@ -887,17 +883,21 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ } else if (family == AF_INET6) {
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct ipv6hdr *ip6 = ipv6_hdr(skb);
+- sin6 = (struct sockaddr_in6 *) msg->msg_name;
+- sin6->sin6_family = AF_INET6;
+- sin6->sin6_port = 0;
+- sin6->sin6_addr = ip6->saddr;
+-
+- sin6->sin6_flowinfo = 0;
+- if (np->sndflow)
+- sin6->sin6_flowinfo = ip6_flowinfo(ip6);
+-
+- sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
+- IP6CB(skb)->iif);
++ struct sockaddr_in6 *sin6 =
++ (struct sockaddr_in6 *)msg->msg_name;
++
++ if (sin6) {
++ sin6->sin6_family = AF_INET6;
++ sin6->sin6_port = 0;
++ sin6->sin6_addr = ip6->saddr;
++ sin6->sin6_flowinfo = 0;
++ if (np->sndflow)
++ sin6->sin6_flowinfo = ip6_flowinfo(ip6);
++ sin6->sin6_scope_id =
++ ipv6_iface_scope_id(&sin6->sin6_addr,
++ IP6CB(skb)->iif);
++ *addr_len = sizeof(*sin6);
++ }
+
+ if (inet6_sk(sk)->rxopt.all)
+ pingv6_ops.ip6_datagram_recv_ctl(sk, msg, skb);
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index 193db03..7d3db78 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -694,11 +694,8 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ if (flags & MSG_OOB)
+ goto out;
+
+- if (addr_len)
+- *addr_len = sizeof(*sin);
+-
+ if (flags & MSG_ERRQUEUE) {
+- err = ip_recv_error(sk, msg, len);
++ err = ip_recv_error(sk, msg, len, addr_len);
+ goto out;
+ }
+
+@@ -724,6 +721,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+ sin->sin_port = 0;
+ memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
++ *addr_len = sizeof(*sin);
+ }
+ if (inet->cmsg_flags)
+ ip_cmsg_recv(msg, skb);
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 6011615..62290b5 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1772,8 +1772,12 @@ local_input:
+ rth->dst.error= -err;
+ rth->rt_flags &= ~RTCF_LOCAL;
+ }
+- if (do_cache)
+- rt_cache_route(&FIB_RES_NH(res), rth);
++ if (do_cache) {
++ if (unlikely(!rt_cache_route(&FIB_RES_NH(res), rth))) {
++ rth->dst.flags |= DST_NOCACHE;
++ rt_add_uncached_list(rth);
++ }
++ }
+ skb_dst_set(skb, &rth->dst);
+ err = 0;
+ goto out;
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 6e5617b..be5246e 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -806,12 +806,6 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
+ xmit_size_goal = min_t(u32, gso_size,
+ sk->sk_gso_max_size - 1 - hlen);
+
+- /* TSQ : try to have at least two segments in flight
+- * (one in NIC TX ring, another in Qdisc)
+- */
+- xmit_size_goal = min_t(u32, xmit_size_goal,
+- sysctl_tcp_limit_output_bytes >> 1);
+-
+ xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
+
+ /* We try hard to avoid divides here */
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index b14266b..5031f68 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -177,7 +177,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+ if (IS_ERR(rt)) {
+ err = PTR_ERR(rt);
+ if (err == -ENETUNREACH)
+- IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
++ IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
+ return err;
+ }
+
+diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
+index 52f3c6b..3107114 100644
+--- a/net/ipv4/tcp_metrics.c
++++ b/net/ipv4/tcp_metrics.c
+@@ -659,10 +659,13 @@ void tcp_fastopen_cache_get(struct sock *sk, u16 *mss,
+ void tcp_fastopen_cache_set(struct sock *sk, u16 mss,
+ struct tcp_fastopen_cookie *cookie, bool syn_lost)
+ {
++ struct dst_entry *dst = __sk_dst_get(sk);
+ struct tcp_metrics_block *tm;
+
++ if (!dst)
++ return;
+ rcu_read_lock();
+- tm = tcp_get_metrics(sk, __sk_dst_get(sk), true);
++ tm = tcp_get_metrics(sk, dst, true);
+ if (tm) {
+ struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen;
+
+diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
+index 533c58a..910ab81 100644
+--- a/net/ipv4/tcp_offload.c
++++ b/net/ipv4/tcp_offload.c
+@@ -272,33 +272,32 @@ static struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *
+ {
+ const struct iphdr *iph = skb_gro_network_header(skb);
+ __wsum wsum;
+- __sum16 sum;
++
++ /* Don't bother verifying checksum if we're going to flush anyway. */
++ if (NAPI_GRO_CB(skb)->flush)
++ goto skip_csum;
++
++ wsum = skb->csum;
+
+ switch (skb->ip_summed) {
++ case CHECKSUM_NONE:
++ wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
++ 0);
++
++ /* fall through */
++
+ case CHECKSUM_COMPLETE:
+ if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr,
+- skb->csum)) {
++ wsum)) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ break;
+ }
+-flush:
++
+ NAPI_GRO_CB(skb)->flush = 1;
+ return NULL;
+-
+- case CHECKSUM_NONE:
+- wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
+- skb_gro_len(skb), IPPROTO_TCP, 0);
+- sum = csum_fold(skb_checksum(skb,
+- skb_gro_offset(skb),
+- skb_gro_len(skb),
+- wsum));
+- if (sum)
+- goto flush;
+-
+- skb->ip_summed = CHECKSUM_UNNECESSARY;
+- break;
+ }
+
++skip_csum:
+ return tcp_gro_receive(head, skb);
+ }
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index d46f214..e912634 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1875,8 +1875,12 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
+ * - better RTT estimation and ACK scheduling
+ * - faster recovery
+ * - high rates
++ * Alas, some drivers / subsystems require a fair amount
++ * of queued bytes to ensure line rate.
++ * One example is wifi aggregation (802.11 AMPDU)
+ */
+- limit = max(skb->truesize, sk->sk_pacing_rate >> 10);
++ limit = max_t(unsigned int, sysctl_tcp_limit_output_bytes,
++ sk->sk_pacing_rate >> 10);
+
+ if (atomic_read(&sk->sk_wmem_alloc) > limit) {
+ set_bit(TSQ_THROTTLED, &tp->tsq_flags);
+@@ -3108,7 +3112,6 @@ void tcp_send_window_probe(struct sock *sk)
+ {
+ if (sk->sk_state == TCP_ESTABLISHED) {
+ tcp_sk(sk)->snd_wl1 = tcp_sk(sk)->rcv_nxt - 1;
+- tcp_sk(sk)->snd_nxt = tcp_sk(sk)->write_seq;
+ tcp_xmit_probe_skb(sk, 0);
+ }
+ }
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 0ca44df..5e2c2f1 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -973,7 +973,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ err = PTR_ERR(rt);
+ rt = NULL;
+ if (err == -ENETUNREACH)
+- IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
++ IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
+ goto out;
+ }
+
+@@ -1072,6 +1072,9 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
+ struct udp_sock *up = udp_sk(sk);
+ int ret;
+
++ if (flags & MSG_SENDPAGE_NOTLAST)
++ flags |= MSG_MORE;
++
+ if (!up->pending) {
+ struct msghdr msg = { .msg_flags = flags|MSG_MORE };
+
+@@ -1209,14 +1212,8 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ int is_udplite = IS_UDPLITE(sk);
+ bool slow;
+
+- /*
+- * Check any passed addresses
+- */
+- if (addr_len)
+- *addr_len = sizeof(*sin);
+-
+ if (flags & MSG_ERRQUEUE)
+- return ip_recv_error(sk, msg, len);
++ return ip_recv_error(sk, msg, len, addr_len);
+
+ try_again:
+ skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
+@@ -1276,6 +1273,7 @@ try_again:
+ sin->sin_port = udp_hdr(skb)->source;
+ sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+ memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
++ *addr_len = sizeof(*sin);
+ }
+ if (inet->cmsg_flags)
+ ip_cmsg_recv(msg, skb);
+diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
+index ccde542..adf9983 100644
+--- a/net/ipv4/xfrm4_policy.c
++++ b/net/ipv4/xfrm4_policy.c
+@@ -104,10 +104,14 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
+ const struct iphdr *iph = ip_hdr(skb);
+ u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
+ struct flowi4 *fl4 = &fl->u.ip4;
++ int oif = 0;
++
++ if (skb_dst(skb))
++ oif = skb_dst(skb)->dev->ifindex;
+
+ memset(fl4, 0, sizeof(struct flowi4));
+ fl4->flowi4_mark = skb->mark;
+- fl4->flowi4_oif = skb_dst(skb)->dev->ifindex;
++ fl4->flowi4_oif = reverse ? skb->skb_iif : oif;
+
+ if (!ip_is_fragment(iph)) {
+ switch (iph->protocol) {
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 7c96100..8132b44 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -965,10 +965,10 @@ out:
+
+ #ifdef CONFIG_SYSCTL
+ sysctl_fail:
+- ipv6_packet_cleanup();
++ pingv6_exit();
+ #endif
+ pingv6_fail:
+- pingv6_exit();
++ ipv6_packet_cleanup();
+ ipv6_packet_fail:
+ tcpv6_exit();
+ tcpv6_fail:
+diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
+index 48b6bd2..c66c6df 100644
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -318,7 +318,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu)
+ /*
+ * Handle MSG_ERRQUEUE
+ */
+-int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
++int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
+ {
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct sock_exterr_skb *serr;
+@@ -369,6 +369,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
+ &sin->sin6_addr);
+ sin->sin6_scope_id = 0;
+ }
++ *addr_len = sizeof(*sin);
+ }
+
+ memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
+@@ -377,6 +378,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
+ if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
+ sin->sin6_family = AF_INET6;
+ sin->sin6_flowinfo = 0;
++ sin->sin6_port = 0;
+ if (skb->protocol == htons(ETH_P_IPV6)) {
+ sin->sin6_addr = ipv6_hdr(skb)->saddr;
+ if (np->rxopt.all)
+@@ -423,7 +425,8 @@ EXPORT_SYMBOL_GPL(ipv6_recv_error);
+ /*
+ * Handle IPV6_RECVPATHMTU
+ */
+-int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
++int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
++ int *addr_len)
+ {
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct sk_buff *skb;
+@@ -457,6 +460,7 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
+ sin->sin6_port = 0;
+ sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id;
+ sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr;
++ *addr_len = sizeof(*sin);
+ }
+
+ put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info);
+diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
+index 46e8843..f0ccdb7 100644
+--- a/net/ipv6/ip6_flowlabel.c
++++ b/net/ipv6/ip6_flowlabel.c
+@@ -453,8 +453,10 @@ static int mem_check(struct sock *sk)
+ if (room > FL_MAX_SIZE - FL_MAX_PER_SOCK)
+ return 0;
+
++ rcu_read_lock_bh();
+ for_each_sk_fl_rcu(np, sfl)
+ count++;
++ rcu_read_unlock_bh();
+
+ if (room <= 0 ||
+ ((count >= FL_MAX_PER_SOCK ||
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 91fb4e8..b6fa35e 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -116,8 +116,8 @@ static int ip6_finish_output2(struct sk_buff *skb)
+ }
+ rcu_read_unlock_bh();
+
+- IP6_INC_STATS_BH(dev_net(dst->dev),
+- ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
++ IP6_INC_STATS(dev_net(dst->dev),
++ ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+@@ -125,7 +125,8 @@ static int ip6_finish_output2(struct sk_buff *skb)
+ static int ip6_finish_output(struct sk_buff *skb)
+ {
+ if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
+- dst_allfrag(skb_dst(skb)))
++ dst_allfrag(skb_dst(skb)) ||
++ (IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size))
+ return ip6_fragment(skb, ip6_finish_output2);
+ else
+ return ip6_finish_output2(skb);
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 583b77e..c1e11b5 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1635,6 +1635,15 @@ static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
+ return ip6_tnl_update(t, &p);
+ }
+
++static void ip6_tnl_dellink(struct net_device *dev, struct list_head *head)
++{
++ struct net *net = dev_net(dev);
++ struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
++
++ if (dev != ip6n->fb_tnl_dev)
++ unregister_netdevice_queue(dev, head);
++}
++
+ static size_t ip6_tnl_get_size(const struct net_device *dev)
+ {
+ return
+@@ -1699,6 +1708,7 @@ static struct rtnl_link_ops ip6_link_ops __read_mostly = {
+ .validate = ip6_tnl_validate,
+ .newlink = ip6_tnl_newlink,
+ .changelink = ip6_tnl_changelink,
++ .dellink = ip6_tnl_dellink,
+ .get_size = ip6_tnl_get_size,
+ .fill_info = ip6_tnl_fill_info,
+ };
+@@ -1715,9 +1725,9 @@ static struct xfrm6_tunnel ip6ip6_handler __read_mostly = {
+ .priority = 1,
+ };
+
+-static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
++static void __net_exit ip6_tnl_destroy_tunnels(struct net *net)
+ {
+- struct net *net = dev_net(ip6n->fb_tnl_dev);
++ struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+ struct net_device *dev, *aux;
+ int h;
+ struct ip6_tnl *t;
+@@ -1785,10 +1795,8 @@ err_alloc_dev:
+
+ static void __net_exit ip6_tnl_exit_net(struct net *net)
+ {
+- struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+-
+ rtnl_lock();
+- ip6_tnl_destroy_tunnels(ip6n);
++ ip6_tnl_destroy_tunnels(net);
+ rtnl_unlock();
+ }
+
+diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+index d6e4dd8..83ab37c 100644
+--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
++++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+@@ -169,63 +169,13 @@ out:
+ return nf_conntrack_confirm(skb);
+ }
+
+-static unsigned int __ipv6_conntrack_in(struct net *net,
+- unsigned int hooknum,
+- struct sk_buff *skb,
+- const struct net_device *in,
+- const struct net_device *out,
+- int (*okfn)(struct sk_buff *))
+-{
+- struct sk_buff *reasm = skb->nfct_reasm;
+- const struct nf_conn_help *help;
+- struct nf_conn *ct;
+- enum ip_conntrack_info ctinfo;
+-
+- /* This packet is fragmented and has reassembled packet. */
+- if (reasm) {
+- /* Reassembled packet isn't parsed yet ? */
+- if (!reasm->nfct) {
+- unsigned int ret;
+-
+- ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
+- if (ret != NF_ACCEPT)
+- return ret;
+- }
+-
+- /* Conntrack helpers need the entire reassembled packet in the
+- * POST_ROUTING hook. In case of unconfirmed connections NAT
+- * might reassign a helper, so the entire packet is also
+- * required.
+- */
+- ct = nf_ct_get(reasm, &ctinfo);
+- if (ct != NULL && !nf_ct_is_untracked(ct)) {
+- help = nfct_help(ct);
+- if ((help && help->helper) || !nf_ct_is_confirmed(ct)) {
+- nf_conntrack_get_reasm(reasm);
+- NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
+- (struct net_device *)in,
+- (struct net_device *)out,
+- okfn, NF_IP6_PRI_CONNTRACK + 1);
+- return NF_DROP_ERR(-ECANCELED);
+- }
+- }
+-
+- nf_conntrack_get(reasm->nfct);
+- skb->nfct = reasm->nfct;
+- skb->nfctinfo = reasm->nfctinfo;
+- return NF_ACCEPT;
+- }
+-
+- return nf_conntrack_in(net, PF_INET6, hooknum, skb);
+-}
+-
+ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
+- return __ipv6_conntrack_in(dev_net(in), hooknum, skb, in, out, okfn);
++ return nf_conntrack_in(dev_net(in), PF_INET6, hooknum, skb);
+ }
+
+ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
+@@ -239,7 +189,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
+ net_notice_ratelimited("ipv6_conntrack_local: packet too short\n");
+ return NF_ACCEPT;
+ }
+- return __ipv6_conntrack_in(dev_net(out), hooknum, skb, in, out, okfn);
++ return nf_conntrack_in(dev_net(out), PF_INET6, hooknum, skb);
+ }
+
+ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
+diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
+index dffdc1a..253566a 100644
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
+@@ -621,31 +621,16 @@ ret_orig:
+ return skb;
+ }
+
+-void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
+- struct net_device *in, struct net_device *out,
+- int (*okfn)(struct sk_buff *))
++void nf_ct_frag6_consume_orig(struct sk_buff *skb)
+ {
+ struct sk_buff *s, *s2;
+- unsigned int ret = 0;
+
+ for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
+- nf_conntrack_put_reasm(s->nfct_reasm);
+- nf_conntrack_get_reasm(skb);
+- s->nfct_reasm = skb;
+-
+ s2 = s->next;
+ s->next = NULL;
+-
+- if (ret != -ECANCELED)
+- ret = NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s,
+- in, out, okfn,
+- NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
+- else
+- kfree_skb(s);
+-
++ consume_skb(s);
+ s = s2;
+ }
+- nf_conntrack_put_reasm(skb);
+ }
+
+ static int nf_ct_net_init(struct net *net)
+diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+index aacd121..581dd9e 100644
+--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
++++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+@@ -75,8 +75,11 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
+ if (reasm == skb)
+ return NF_ACCEPT;
+
+- nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
+- (struct net_device *)out, okfn);
++ nf_ct_frag6_consume_orig(reasm);
++
++ NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
++ (struct net_device *) in, (struct net_device *) out,
++ okfn, NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
+
+ return NF_STOLEN;
+ }
+diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
+index 18f19df..7856e96 100644
+--- a/net/ipv6/ping.c
++++ b/net/ipv6/ping.c
+@@ -57,7 +57,8 @@ static struct inet_protosw pingv6_protosw = {
+
+
+ /* Compatibility glue so we can support IPv6 when it's compiled as a module */
+-static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
++static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
++ int *addr_len)
+ {
+ return -EAFNOSUPPORT;
+ }
+diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
+index a4ed241..430067c 100644
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -466,14 +466,11 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
+ if (flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+- if (addr_len)
+- *addr_len=sizeof(*sin6);
+-
+ if (flags & MSG_ERRQUEUE)
+- return ipv6_recv_error(sk, msg, len);
++ return ipv6_recv_error(sk, msg, len, addr_len);
+
+ if (np->rxpmtu && np->rxopt.bits.rxpmtu)
+- return ipv6_recv_rxpmtu(sk, msg, len);
++ return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
+
+ skb = skb_recv_datagram(sk, flags, noblock, &err);
+ if (!skb)
+@@ -507,6 +504,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
+ sin6->sin6_flowinfo = 0;
+ sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
+ IP6CB(skb)->iif);
++ *addr_len = sizeof(*sin6);
+ }
+
+ sock_recv_ts_and_drops(msg, sk, skb);
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 04e17b3..77308af 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -731,8 +731,11 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
+ prefix = &prefix_buf;
+ }
+
+- rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, gwaddr,
+- dev->ifindex);
++ if (rinfo->prefix_len == 0)
++ rt = rt6_get_dflt_router(gwaddr, dev);
++ else
++ rt = rt6_get_route_info(net, prefix, rinfo->prefix_len,
++ gwaddr, dev->ifindex);
+
+ if (rt && !lifetime) {
+ ip6_del_rt(rt);
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 1926945..b433884 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -1594,6 +1594,15 @@ static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = {
+ #endif
+ };
+
++static void ipip6_dellink(struct net_device *dev, struct list_head *head)
++{
++ struct net *net = dev_net(dev);
++ struct sit_net *sitn = net_generic(net, sit_net_id);
++
++ if (dev != sitn->fb_tunnel_dev)
++ unregister_netdevice_queue(dev, head);
++}
++
+ static struct rtnl_link_ops sit_link_ops __read_mostly = {
+ .kind = "sit",
+ .maxtype = IFLA_IPTUN_MAX,
+@@ -1605,6 +1614,7 @@ static struct rtnl_link_ops sit_link_ops __read_mostly = {
+ .changelink = ipip6_changelink,
+ .get_size = ipip6_get_size,
+ .fill_info = ipip6_fill_info,
++ .dellink = ipip6_dellink,
+ };
+
+ static struct xfrm_tunnel sit_handler __read_mostly = {
+@@ -1619,9 +1629,10 @@ static struct xfrm_tunnel ipip_handler __read_mostly = {
+ .priority = 2,
+ };
+
+-static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head)
++static void __net_exit sit_destroy_tunnels(struct net *net,
++ struct list_head *head)
+ {
+- struct net *net = dev_net(sitn->fb_tunnel_dev);
++ struct sit_net *sitn = net_generic(net, sit_net_id);
+ struct net_device *dev, *aux;
+ int prio;
+
+@@ -1696,11 +1707,10 @@ err_alloc_dev:
+
+ static void __net_exit sit_exit_net(struct net *net)
+ {
+- struct sit_net *sitn = net_generic(net, sit_net_id);
+ LIST_HEAD(list);
+
+ rtnl_lock();
+- sit_destroy_tunnels(sitn, &list);
++ sit_destroy_tunnels(net, &list);
+ unregister_netdevice_many(&list);
+ rtnl_unlock();
+ }
+diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
+index 2ec6bf6..a7a2384 100644
+--- a/net/ipv6/tcpv6_offload.c
++++ b/net/ipv6/tcpv6_offload.c
+@@ -37,34 +37,32 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
+ {
+ const struct ipv6hdr *iph = skb_gro_network_header(skb);
+ __wsum wsum;
+- __sum16 sum;
++
++ /* Don't bother verifying checksum if we're going to flush anyway. */
++ if (NAPI_GRO_CB(skb)->flush)
++ goto skip_csum;
++
++ wsum = skb->csum;
+
+ switch (skb->ip_summed) {
++ case CHECKSUM_NONE:
++ wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
++ wsum);
++
++ /* fall through */
++
+ case CHECKSUM_COMPLETE:
+ if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
+- skb->csum)) {
++ wsum)) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ break;
+ }
+-flush:
++
+ NAPI_GRO_CB(skb)->flush = 1;
+ return NULL;
+-
+- case CHECKSUM_NONE:
+- wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
+- skb_gro_len(skb),
+- IPPROTO_TCP, 0));
+- sum = csum_fold(skb_checksum(skb,
+- skb_gro_offset(skb),
+- skb_gro_len(skb),
+- wsum));
+- if (sum)
+- goto flush;
+-
+- skb->ip_summed = CHECKSUM_UNNECESSARY;
+- break;
+ }
+
++skip_csum:
+ return tcp_gro_receive(head, skb);
+ }
+
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 1878609..3d2758d 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -374,14 +374,11 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
+ int is_udp4;
+ bool slow;
+
+- if (addr_len)
+- *addr_len = sizeof(struct sockaddr_in6);
+-
+ if (flags & MSG_ERRQUEUE)
+- return ipv6_recv_error(sk, msg, len);
++ return ipv6_recv_error(sk, msg, len, addr_len);
+
+ if (np->rxpmtu && np->rxopt.bits.rxpmtu)
+- return ipv6_recv_rxpmtu(sk, msg, len);
++ return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
+
+ try_again:
+ skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
+@@ -462,7 +459,7 @@ try_again:
+ ipv6_iface_scope_id(&sin6->sin6_addr,
+ IP6CB(skb)->iif);
+ }
+-
++ *addr_len = sizeof(*sin6);
+ }
+ if (is_udp4) {
+ if (inet->cmsg_flags)
+diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
+index 6055951..34c6fff 100644
+--- a/net/ipv6/udp_offload.c
++++ b/net/ipv6/udp_offload.c
+@@ -88,7 +88,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
+
+ /* Check if there is enough headroom to insert fragment header. */
+ tnl_hlen = skb_tnl_header_len(skb);
+- if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) {
++ if (skb->mac_header < (tnl_hlen + frag_hdr_sz)) {
+ if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz))
+ goto out;
+ }
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index 08ed277..550b195 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -135,10 +135,14 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
+ struct ipv6_opt_hdr *exthdr;
+ const unsigned char *nh = skb_network_header(skb);
+ u8 nexthdr = nh[IP6CB(skb)->nhoff];
++ int oif = 0;
++
++ if (skb_dst(skb))
++ oif = skb_dst(skb)->dev->ifindex;
+
+ memset(fl6, 0, sizeof(struct flowi6));
+ fl6->flowi6_mark = skb->mark;
+- fl6->flowi6_oif = skb_dst(skb)->dev->ifindex;
++ fl6->flowi6_oif = reverse ? skb->skb_iif : oif;
+
+ fl6->daddr = reverse ? hdr->saddr : hdr->daddr;
+ fl6->saddr = reverse ? hdr->daddr : hdr->saddr;
+diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
+index 7a1e0fc..e096025 100644
+--- a/net/ipx/af_ipx.c
++++ b/net/ipx/af_ipx.c
+@@ -1823,8 +1823,6 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (skb->tstamp.tv64)
+ sk->sk_stamp = skb->tstamp;
+
+- msg->msg_namelen = sizeof(*sipx);
+-
+ if (sipx) {
+ sipx->sipx_family = AF_IPX;
+ sipx->sipx_port = ipx->ipx_source.sock;
+@@ -1832,6 +1830,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
+ sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net;
+ sipx->sipx_type = ipx->ipx_type;
+ sipx->sipx_zero = 0;
++ msg->msg_namelen = sizeof(*sipx);
+ }
+ rc = copied;
+
+diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
+index 0578d4f..a5e62ef5 100644
+--- a/net/irda/af_irda.c
++++ b/net/irda/af_irda.c
+@@ -1385,8 +1385,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
+
+ IRDA_DEBUG(4, "%s()\n", __func__);
+
+- msg->msg_namelen = 0;
+-
+ skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
+ flags & MSG_DONTWAIT, &err);
+ if (!skb)
+@@ -1451,8 +1449,6 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
+ timeo = sock_rcvtimeo(sk, noblock);
+
+- msg->msg_namelen = 0;
+-
+ do {
+ int chunk;
+ struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 168aff5..c4b7218 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1324,8 +1324,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+ int err = 0;
+ u32 offset;
+
+- msg->msg_namelen = 0;
+-
+ if ((sk->sk_state == IUCV_DISCONN) &&
+ skb_queue_empty(&iucv->backlog_skb_q) &&
+ skb_queue_empty(&sk->sk_receive_queue) &&
+diff --git a/net/key/af_key.c b/net/key/af_key.c
+index 911ef03..545f047 100644
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -3616,7 +3616,6 @@ static int pfkey_recvmsg(struct kiocb *kiocb,
+ if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
+ goto out;
+
+- msg->msg_namelen = 0;
+ skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
+ if (skb == NULL)
+ goto out;
+diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
+index 571db8d..da1a1ce 100644
+--- a/net/l2tp/l2tp_ip.c
++++ b/net/l2tp/l2tp_ip.c
+@@ -518,9 +518,6 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
+ if (flags & MSG_OOB)
+ goto out;
+
+- if (addr_len)
+- *addr_len = sizeof(*sin);
+-
+ skb = skb_recv_datagram(sk, flags, noblock, &err);
+ if (!skb)
+ goto out;
+@@ -543,6 +540,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
+ sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+ sin->sin_port = 0;
+ memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
++ *addr_len = sizeof(*sin);
+ }
+ if (inet->cmsg_flags)
+ ip_cmsg_recv(msg, skb);
+diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
+index b8a6039..e6e8408 100644
+--- a/net/l2tp/l2tp_ip6.c
++++ b/net/l2tp/l2tp_ip6.c
+@@ -665,7 +665,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
+ *addr_len = sizeof(*lsa);
+
+ if (flags & MSG_ERRQUEUE)
+- return ipv6_recv_error(sk, msg, len);
++ return ipv6_recv_error(sk, msg, len, addr_len);
+
+ skb = skb_recv_datagram(sk, flags, noblock, &err);
+ if (!skb)
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index 8c46b27..44441c0 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -197,8 +197,6 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (sk->sk_state & PPPOX_BOUND)
+ goto end;
+
+- msg->msg_namelen = 0;
+-
+ err = 0;
+ skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
+ flags & MSG_DONTWAIT, &err);
+diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
+index 6cba486..7b01b9f 100644
+--- a/net/llc/af_llc.c
++++ b/net/llc/af_llc.c
+@@ -720,8 +720,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
+ int target; /* Read at least this many bytes */
+ long timeo;
+
+- msg->msg_namelen = 0;
+-
+ lock_sock(sk);
+ copied = -ENOTCONN;
+ if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
+diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
+index 74fd00c..3581736 100644
+--- a/net/netfilter/ipvs/ip_vs_core.c
++++ b/net/netfilter/ipvs/ip_vs_core.c
+@@ -1139,12 +1139,6 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
+ ip_vs_fill_iph_skb(af, skb, &iph);
+ #ifdef CONFIG_IP_VS_IPV6
+ if (af == AF_INET6) {
+- if (!iph.fragoffs && skb_nfct_reasm(skb)) {
+- struct sk_buff *reasm = skb_nfct_reasm(skb);
+- /* Save fw mark for coming frags */
+- reasm->ipvs_property = 1;
+- reasm->mark = skb->mark;
+- }
+ if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
+ int related;
+ int verdict = ip_vs_out_icmp_v6(skb, &related,
+@@ -1614,12 +1608,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
+
+ #ifdef CONFIG_IP_VS_IPV6
+ if (af == AF_INET6) {
+- if (!iph.fragoffs && skb_nfct_reasm(skb)) {
+- struct sk_buff *reasm = skb_nfct_reasm(skb);
+- /* Save fw mark for coming frags. */
+- reasm->ipvs_property = 1;
+- reasm->mark = skb->mark;
+- }
+ if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
+ int related;
+ int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum,
+@@ -1671,9 +1659,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
+ /* sorry, all this trouble for a no-hit :) */
+ IP_VS_DBG_PKT(12, af, pp, skb, 0,
+ "ip_vs_in: packet continues traversal as normal");
+- if (iph.fragoffs && !skb_nfct_reasm(skb)) {
++ if (iph.fragoffs) {
+ /* Fragment that couldn't be mapped to a conn entry
+- * and don't have any pointer to a reasm skb
+ * is missing module nf_defrag_ipv6
+ */
+ IP_VS_DBG_RL("Unhandled frag, load nf_defrag_ipv6\n");
+@@ -1756,38 +1743,6 @@ ip_vs_local_request4(unsigned int hooknum, struct sk_buff *skb,
+ #ifdef CONFIG_IP_VS_IPV6
+
+ /*
+- * AF_INET6 fragment handling
+- * Copy info from first fragment, to the rest of them.
+- */
+-static unsigned int
+-ip_vs_preroute_frag6(unsigned int hooknum, struct sk_buff *skb,
+- const struct net_device *in,
+- const struct net_device *out,
+- int (*okfn)(struct sk_buff *))
+-{
+- struct sk_buff *reasm = skb_nfct_reasm(skb);
+- struct net *net;
+-
+- /* Skip if not a "replay" from nf_ct_frag6_output or first fragment.
+- * ipvs_property is set when checking first fragment
+- * in ip_vs_in() and ip_vs_out().
+- */
+- if (reasm)
+- IP_VS_DBG(2, "Fragment recv prop:%d\n", reasm->ipvs_property);
+- if (!reasm || !reasm->ipvs_property)
+- return NF_ACCEPT;
+-
+- net = skb_net(skb);
+- if (!net_ipvs(net)->enable)
+- return NF_ACCEPT;
+-
+- /* Copy stored fw mark, saved in ip_vs_{in,out} */
+- skb->mark = reasm->mark;
+-
+- return NF_ACCEPT;
+-}
+-
+-/*
+ * AF_INET6 handler in NF_INET_LOCAL_IN chain
+ * Schedule and forward packets from remote clients
+ */
+@@ -1924,14 +1879,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
+ .priority = 100,
+ },
+ #ifdef CONFIG_IP_VS_IPV6
+- /* After mangle & nat fetch 2:nd fragment and following */
+- {
+- .hook = ip_vs_preroute_frag6,
+- .owner = THIS_MODULE,
+- .pf = NFPROTO_IPV6,
+- .hooknum = NF_INET_PRE_ROUTING,
+- .priority = NF_IP6_PRI_NAT_DST + 1,
+- },
+ /* After packet filtering, change source only for VS/NAT */
+ {
+ .hook = ip_vs_reply6,
+diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c
+index 9ef22bd..bed5f70 100644
+--- a/net/netfilter/ipvs/ip_vs_pe_sip.c
++++ b/net/netfilter/ipvs/ip_vs_pe_sip.c
+@@ -65,7 +65,6 @@ static int get_callid(const char *dptr, unsigned int dataoff,
+ static int
+ ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb)
+ {
+- struct sk_buff *reasm = skb_nfct_reasm(skb);
+ struct ip_vs_iphdr iph;
+ unsigned int dataoff, datalen, matchoff, matchlen;
+ const char *dptr;
+@@ -79,15 +78,10 @@ ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb)
+ /* todo: IPv6 fragments:
+ * I think this only should be done for the first fragment. /HS
+ */
+- if (reasm) {
+- skb = reasm;
+- dataoff = iph.thoff_reasm + sizeof(struct udphdr);
+- } else
+- dataoff = iph.len + sizeof(struct udphdr);
++ dataoff = iph.len + sizeof(struct udphdr);
+
+ if (dataoff >= skb->len)
+ return -EINVAL;
+- /* todo: Check if this will mess-up the reasm skb !!! /HS */
+ retc = skb_linearize(skb);
+ if (retc < 0)
+ return retc;
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 8df7f64..6135635 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -2335,8 +2335,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
+ }
+ #endif
+
+- msg->msg_namelen = 0;
+-
+ copied = data_skb->len;
+ if (len < copied) {
+ msg->msg_flags |= MSG_TRUNC;
+diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
+index 698814b..53c19a3 100644
+--- a/net/netrom/af_netrom.c
++++ b/net/netrom/af_netrom.c
+@@ -1179,10 +1179,9 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
+ sax->sax25_family = AF_NETROM;
+ skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
+ AX25_ADDR_LEN);
++ msg->msg_namelen = sizeof(*sax);
+ }
+
+- msg->msg_namelen = sizeof(*sax);
+-
+ skb_free_datagram(sk, skb);
+
+ release_sock(sk);
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index d308402..824c605 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -807,8 +807,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+
+ pr_debug("%p %zu\n", sk, len);
+
+- msg->msg_namelen = 0;
+-
+ lock_sock(sk);
+
+ if (sk->sk_state == LLCP_CLOSED &&
+diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
+index 313bf1b..5d11f4a 100644
+--- a/net/nfc/rawsock.c
++++ b/net/nfc/rawsock.c
+@@ -241,8 +241,6 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (!skb)
+ return rc;
+
+- msg->msg_namelen = 0;
+-
+ copied = skb->len;
+ if (len < copied) {
+ msg->msg_flags |= MSG_TRUNC;
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 2e8286b..ba2548b 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -244,11 +244,15 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po);
+ static void register_prot_hook(struct sock *sk)
+ {
+ struct packet_sock *po = pkt_sk(sk);
++
+ if (!po->running) {
+- if (po->fanout)
++ if (po->fanout) {
+ __fanout_link(sk, po);
+- else
++ } else {
+ dev_add_pack(&po->prot_hook);
++ rcu_assign_pointer(po->cached_dev, po->prot_hook.dev);
++ }
++
+ sock_hold(sk);
+ po->running = 1;
+ }
+@@ -266,10 +270,13 @@ static void __unregister_prot_hook(struct sock *sk, bool sync)
+ struct packet_sock *po = pkt_sk(sk);
+
+ po->running = 0;
+- if (po->fanout)
++ if (po->fanout) {
+ __fanout_unlink(sk, po);
+- else
++ } else {
+ __dev_remove_pack(&po->prot_hook);
++ RCU_INIT_POINTER(po->cached_dev, NULL);
++ }
++
+ __sock_put(sk);
+
+ if (sync) {
+@@ -432,9 +439,9 @@ static void prb_shutdown_retire_blk_timer(struct packet_sock *po,
+
+ pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc;
+
+- spin_lock(&rb_queue->lock);
++ spin_lock_bh(&rb_queue->lock);
+ pkc->delete_blk_timer = 1;
+- spin_unlock(&rb_queue->lock);
++ spin_unlock_bh(&rb_queue->lock);
+
+ prb_del_retire_blk_timer(pkc);
+ }
+@@ -2052,12 +2059,24 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
+ return tp_len;
+ }
+
++static struct net_device *packet_cached_dev_get(struct packet_sock *po)
++{
++ struct net_device *dev;
++
++ rcu_read_lock();
++ dev = rcu_dereference(po->cached_dev);
++ if (dev)
++ dev_hold(dev);
++ rcu_read_unlock();
++
++ return dev;
++}
++
+ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
+ {
+ struct sk_buff *skb;
+ struct net_device *dev;
+ __be16 proto;
+- bool need_rls_dev = false;
+ int err, reserve = 0;
+ void *ph;
+ struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
+@@ -2070,7 +2089,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
+ mutex_lock(&po->pg_vec_lock);
+
+ if (saddr == NULL) {
+- dev = po->prot_hook.dev;
++ dev = packet_cached_dev_get(po);
+ proto = po->num;
+ addr = NULL;
+ } else {
+@@ -2084,19 +2103,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
+ proto = saddr->sll_protocol;
+ addr = saddr->sll_addr;
+ dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
+- need_rls_dev = true;
+ }
+
+ err = -ENXIO;
+ if (unlikely(dev == NULL))
+ goto out;
+-
+- reserve = dev->hard_header_len;
+-
+ err = -ENETDOWN;
+ if (unlikely(!(dev->flags & IFF_UP)))
+ goto out_put;
+
++ reserve = dev->hard_header_len;
++
+ size_max = po->tx_ring.frame_size
+ - (po->tp_hdrlen - sizeof(struct sockaddr_ll));
+
+@@ -2173,8 +2190,7 @@ out_status:
+ __packet_set_status(po, ph, status);
+ kfree_skb(skb);
+ out_put:
+- if (need_rls_dev)
+- dev_put(dev);
++ dev_put(dev);
+ out:
+ mutex_unlock(&po->pg_vec_lock);
+ return err;
+@@ -2212,7 +2228,6 @@ static int packet_snd(struct socket *sock,
+ struct sk_buff *skb;
+ struct net_device *dev;
+ __be16 proto;
+- bool need_rls_dev = false;
+ unsigned char *addr;
+ int err, reserve = 0;
+ struct virtio_net_hdr vnet_hdr = { 0 };
+@@ -2228,7 +2243,7 @@ static int packet_snd(struct socket *sock,
+ */
+
+ if (saddr == NULL) {
+- dev = po->prot_hook.dev;
++ dev = packet_cached_dev_get(po);
+ proto = po->num;
+ addr = NULL;
+ } else {
+@@ -2240,19 +2255,17 @@ static int packet_snd(struct socket *sock,
+ proto = saddr->sll_protocol;
+ addr = saddr->sll_addr;
+ dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex);
+- need_rls_dev = true;
+ }
+
+ err = -ENXIO;
+- if (dev == NULL)
++ if (unlikely(dev == NULL))
+ goto out_unlock;
+- if (sock->type == SOCK_RAW)
+- reserve = dev->hard_header_len;
+-
+ err = -ENETDOWN;
+- if (!(dev->flags & IFF_UP))
++ if (unlikely(!(dev->flags & IFF_UP)))
+ goto out_unlock;
+
++ if (sock->type == SOCK_RAW)
++ reserve = dev->hard_header_len;
+ if (po->has_vnet_hdr) {
+ vnet_hdr_len = sizeof(vnet_hdr);
+
+@@ -2386,15 +2399,14 @@ static int packet_snd(struct socket *sock,
+ if (err > 0 && (err = net_xmit_errno(err)) != 0)
+ goto out_unlock;
+
+- if (need_rls_dev)
+- dev_put(dev);
++ dev_put(dev);
+
+ return len;
+
+ out_free:
+ kfree_skb(skb);
+ out_unlock:
+- if (dev && need_rls_dev)
++ if (dev)
+ dev_put(dev);
+ out:
+ return err;
+@@ -2614,6 +2626,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
+ po = pkt_sk(sk);
+ sk->sk_family = PF_PACKET;
+ po->num = proto;
++ RCU_INIT_POINTER(po->cached_dev, NULL);
+
+ sk->sk_destruct = packet_sock_destruct;
+ sk_refcnt_debug_inc(sk);
+@@ -2660,7 +2673,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct sock *sk = sock->sk;
+ struct sk_buff *skb;
+ int copied, err;
+- struct sockaddr_ll *sll;
+ int vnet_hdr_len = 0;
+
+ err = -EINVAL;
+@@ -2744,22 +2756,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
+ goto out_free;
+ }
+
+- /*
+- * If the address length field is there to be filled in, we fill
+- * it in now.
++ /* You lose any data beyond the buffer you gave. If it worries
++ * a user program they can ask the device for its MTU
++ * anyway.
+ */
+-
+- sll = &PACKET_SKB_CB(skb)->sa.ll;
+- if (sock->type == SOCK_PACKET)
+- msg->msg_namelen = sizeof(struct sockaddr_pkt);
+- else
+- msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
+-
+- /*
+- * You lose any data beyond the buffer you gave. If it worries a
+- * user program they can ask the device for its MTU anyway.
+- */
+-
+ copied = skb->len;
+ if (copied > len) {
+ copied = len;
+@@ -2772,9 +2772,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
+
+ sock_recv_ts_and_drops(msg, sk, skb);
+
+- if (msg->msg_name)
++ if (msg->msg_name) {
++ /* If the address length field is there to be filled
++ * in, we fill it in now.
++ */
++ if (sock->type == SOCK_PACKET) {
++ msg->msg_namelen = sizeof(struct sockaddr_pkt);
++ } else {
++ struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
++ msg->msg_namelen = sll->sll_halen +
++ offsetof(struct sockaddr_ll, sll_addr);
++ }
+ memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
+ msg->msg_namelen);
++ }
+
+ if (pkt_sk(sk)->auxdata) {
+ struct tpacket_auxdata aux;
+diff --git a/net/packet/internal.h b/net/packet/internal.h
+index c4e4b45..1035fa2 100644
+--- a/net/packet/internal.h
++++ b/net/packet/internal.h
+@@ -113,6 +113,7 @@ struct packet_sock {
+ unsigned int tp_loss:1;
+ unsigned int tp_tx_has_off:1;
+ unsigned int tp_tstamp;
++ struct net_device __rcu *cached_dev;
+ struct packet_type prot_hook ____cacheline_aligned_in_smp;
+ };
+
+diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
+index 12c30f3..38946b2 100644
+--- a/net/phonet/datagram.c
++++ b/net/phonet/datagram.c
+@@ -139,9 +139,6 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
+ MSG_CMSG_COMPAT))
+ goto out_nofree;
+
+- if (addr_len)
+- *addr_len = sizeof(sa);
+-
+ skb = skb_recv_datagram(sk, flags, noblock, &rval);
+ if (skb == NULL)
+ goto out_nofree;
+@@ -162,8 +159,10 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
+
+ rval = (flags & MSG_TRUNC) ? skb->len : copylen;
+
+- if (msg->msg_name != NULL)
+- memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn));
++ if (msg->msg_name != NULL) {
++ memcpy(msg->msg_name, &sa, sizeof(sa));
++ *addr_len = sizeof(sa);
++ }
+
+ out:
+ skb_free_datagram(sk, skb);
+diff --git a/net/rds/recv.c b/net/rds/recv.c
+index 9f0f17c..de339b2 100644
+--- a/net/rds/recv.c
++++ b/net/rds/recv.c
+@@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+
+ rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
+
+- msg->msg_namelen = 0;
+-
+ if (msg_flags & MSG_OOB)
+ goto out;
+
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index e98fcfb..33af772 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -1216,7 +1216,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
+ {
+ struct sock *sk = sock->sk;
+ struct rose_sock *rose = rose_sk(sk);
+- struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name;
+ size_t copied;
+ unsigned char *asmptr;
+ struct sk_buff *skb;
+@@ -1252,8 +1251,11 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
+
+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+
+- if (srose != NULL) {
+- memset(srose, 0, msg->msg_namelen);
++ if (msg->msg_name) {
++ struct sockaddr_rose *srose;
++
++ memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
++ srose = msg->msg_name;
+ srose->srose_family = AF_ROSE;
+ srose->srose_addr = rose->dest_addr;
+ srose->srose_call = rose->dest_call;
+diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c
+index 4b48687..898492a 100644
+--- a/net/rxrpc/ar-recvmsg.c
++++ b/net/rxrpc/ar-recvmsg.c
+@@ -143,10 +143,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
+
+ /* copy the peer address and timestamp */
+ if (!continue_call) {
+- if (msg->msg_name && msg->msg_namelen > 0)
++ if (msg->msg_name) {
++ size_t len =
++ sizeof(call->conn->trans->peer->srx);
+ memcpy(msg->msg_name,
+- &call->conn->trans->peer->srx,
+- sizeof(call->conn->trans->peer->srx));
++ &call->conn->trans->peer->srx, len);
++ msg->msg_namelen = len;
++ }
+ sock_recv_ts_and_drops(msg, &rx->sk, skb);
+ }
+
+diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
+index a9dfdda..2e55f81 100644
+--- a/net/sched/sch_fq.c
++++ b/net/sched/sch_fq.c
+@@ -88,7 +88,7 @@ struct fq_sched_data {
+ struct fq_flow internal; /* for non classified or high prio packets */
+ u32 quantum;
+ u32 initial_quantum;
+- u32 flow_default_rate;/* rate per flow : bytes per second */
++ u32 flow_refill_delay;
+ u32 flow_max_rate; /* optional max rate per flow */
+ u32 flow_plimit; /* max packets per flow */
+ struct rb_root *fq_root;
+@@ -115,6 +115,7 @@ static struct fq_flow detached, throttled;
+ static void fq_flow_set_detached(struct fq_flow *f)
+ {
+ f->next = &detached;
++ f->age = jiffies;
+ }
+
+ static bool fq_flow_is_detached(const struct fq_flow *f)
+@@ -209,21 +210,15 @@ static void fq_gc(struct fq_sched_data *q,
+ }
+ }
+
+-static const u8 prio2band[TC_PRIO_MAX + 1] = {
+- 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1
+-};
+-
+ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q)
+ {
+ struct rb_node **p, *parent;
+ struct sock *sk = skb->sk;
+ struct rb_root *root;
+ struct fq_flow *f;
+- int band;
+
+ /* warning: no starvation prevention... */
+- band = prio2band[skb->priority & TC_PRIO_MAX];
+- if (unlikely(band == 0))
++ if (unlikely((skb->priority & TC_PRIO_MAX) == TC_PRIO_CONTROL))
+ return &q->internal;
+
+ if (unlikely(!sk)) {
+@@ -372,17 +367,20 @@ static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+ }
+
+ f->qlen++;
+- flow_queue_add(f, skb);
+ if (skb_is_retransmit(skb))
+ q->stat_tcp_retrans++;
+ sch->qstats.backlog += qdisc_pkt_len(skb);
+ if (fq_flow_is_detached(f)) {
+ fq_flow_add_tail(&q->new_flows, f);
+- if (q->quantum > f->credit)
+- f->credit = q->quantum;
++ if (time_after(jiffies, f->age + q->flow_refill_delay))
++ f->credit = max_t(u32, f->credit, q->quantum);
+ q->inactive_flows--;
+ qdisc_unthrottled(sch);
+ }
++
++ /* Note: this overwrites f->age */
++ flow_queue_add(f, skb);
++
+ if (unlikely(f == &q->internal)) {
+ q->stat_internal_packets++;
+ qdisc_unthrottled(sch);
+@@ -460,7 +458,6 @@ begin:
+ fq_flow_add_tail(&q->old_flows, f);
+ } else {
+ fq_flow_set_detached(f);
+- f->age = jiffies;
+ q->inactive_flows++;
+ }
+ goto begin;
+@@ -614,6 +611,7 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
+ [TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NLA_U32 },
+ [TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 },
+ [TCA_FQ_BUCKETS_LOG] = { .type = NLA_U32 },
++ [TCA_FQ_FLOW_REFILL_DELAY] = { .type = NLA_U32 },
+ };
+
+ static int fq_change(struct Qdisc *sch, struct nlattr *opt)
+@@ -655,7 +653,8 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt)
+ q->initial_quantum = nla_get_u32(tb[TCA_FQ_INITIAL_QUANTUM]);
+
+ if (tb[TCA_FQ_FLOW_DEFAULT_RATE])
+- q->flow_default_rate = nla_get_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]);
++ pr_warn_ratelimited("sch_fq: defrate %u ignored.\n",
++ nla_get_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]));
+
+ if (tb[TCA_FQ_FLOW_MAX_RATE])
+ q->flow_max_rate = nla_get_u32(tb[TCA_FQ_FLOW_MAX_RATE]);
+@@ -669,6 +668,12 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt)
+ err = -EINVAL;
+ }
+
++ if (tb[TCA_FQ_FLOW_REFILL_DELAY]) {
++ u32 usecs_delay = nla_get_u32(tb[TCA_FQ_FLOW_REFILL_DELAY]) ;
++
++ q->flow_refill_delay = usecs_to_jiffies(usecs_delay);
++ }
++
+ if (!err)
+ err = fq_resize(q, fq_log);
+
+@@ -704,7 +709,7 @@ static int fq_init(struct Qdisc *sch, struct nlattr *opt)
+ q->flow_plimit = 100;
+ q->quantum = 2 * psched_mtu(qdisc_dev(sch));
+ q->initial_quantum = 10 * psched_mtu(qdisc_dev(sch));
+- q->flow_default_rate = 0;
++ q->flow_refill_delay = msecs_to_jiffies(40);
+ q->flow_max_rate = ~0U;
+ q->rate_enable = 1;
+ q->new_flows.first = NULL;
+@@ -731,15 +736,16 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb)
+ if (opts == NULL)
+ goto nla_put_failure;
+
+- /* TCA_FQ_FLOW_DEFAULT_RATE is not used anymore,
+- * do not bother giving its value
+- */
++ /* TCA_FQ_FLOW_DEFAULT_RATE is not used anymore */
++
+ if (nla_put_u32(skb, TCA_FQ_PLIMIT, sch->limit) ||
+ nla_put_u32(skb, TCA_FQ_FLOW_PLIMIT, q->flow_plimit) ||
+ nla_put_u32(skb, TCA_FQ_QUANTUM, q->quantum) ||
+ nla_put_u32(skb, TCA_FQ_INITIAL_QUANTUM, q->initial_quantum) ||
+ nla_put_u32(skb, TCA_FQ_RATE_ENABLE, q->rate_enable) ||
+ nla_put_u32(skb, TCA_FQ_FLOW_MAX_RATE, q->flow_max_rate) ||
++ nla_put_u32(skb, TCA_FQ_FLOW_REFILL_DELAY,
++ jiffies_to_usecs(q->flow_refill_delay)) ||
+ nla_put_u32(skb, TCA_FQ_BUCKETS_LOG, q->fq_trees_log))
+ goto nla_put_failure;
+
+diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
+index 1aaf1b6..6ddda28 100644
+--- a/net/sched/sch_tbf.c
++++ b/net/sched/sch_tbf.c
+@@ -21,6 +21,7 @@
+ #include <net/netlink.h>
+ #include <net/sch_generic.h>
+ #include <net/pkt_sched.h>
++#include <net/tcp.h>
+
+
+ /* Simple Token Bucket Filter.
+@@ -117,6 +118,22 @@ struct tbf_sched_data {
+ };
+
+
++/*
++ * Return length of individual segments of a gso packet,
++ * including all headers (MAC, IP, TCP/UDP)
++ */
++static unsigned int skb_gso_seglen(const struct sk_buff *skb)
++{
++ unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
++ const struct skb_shared_info *shinfo = skb_shinfo(skb);
++
++ if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
++ hdr_len += tcp_hdrlen(skb);
++ else
++ hdr_len += sizeof(struct udphdr);
++ return hdr_len + shinfo->gso_size;
++}
++
+ /* GSO packet is too big, segment it so that tbf can transmit
+ * each segment in time
+ */
+@@ -136,12 +153,8 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch)
+ while (segs) {
+ nskb = segs->next;
+ segs->next = NULL;
+- if (likely(segs->len <= q->max_size)) {
+- qdisc_skb_cb(segs)->pkt_len = segs->len;
+- ret = qdisc_enqueue(segs, q->qdisc);
+- } else {
+- ret = qdisc_reshape_fail(skb, sch);
+- }
++ qdisc_skb_cb(segs)->pkt_len = segs->len;
++ ret = qdisc_enqueue(segs, q->qdisc);
+ if (ret != NET_XMIT_SUCCESS) {
+ if (net_xmit_drop_count(ret))
+ sch->qstats.drops++;
+@@ -163,7 +176,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+ int ret;
+
+ if (qdisc_pkt_len(skb) > q->max_size) {
+- if (skb_is_gso(skb))
++ if (skb_is_gso(skb) && skb_gso_seglen(skb) <= q->max_size)
+ return tbf_segment(skb, sch);
+ return qdisc_reshape_fail(skb, sch);
+ }
+@@ -316,6 +329,11 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
+ if (max_size < 0)
+ goto done;
+
++ if (max_size < psched_mtu(qdisc_dev(sch)))
++ pr_warn_ratelimited("sch_tbf: burst %u is lower than device %s mtu (%u) !\n",
++ max_size, qdisc_dev(sch)->name,
++ psched_mtu(qdisc_dev(sch)));
++
+ if (q->qdisc != &noop_qdisc) {
+ err = fifo_set_limit(q->qdisc, qopt->limit);
+ if (err)
+diff --git a/net/socket.c b/net/socket.c
+index c226ace..e83c416 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -221,12 +221,13 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
+ int err;
+ int len;
+
++ BUG_ON(klen > sizeof(struct sockaddr_storage));
+ err = get_user(len, ulen);
+ if (err)
+ return err;
+ if (len > klen)
+ len = klen;
+- if (len < 0 || len > sizeof(struct sockaddr_storage))
++ if (len < 0)
+ return -EINVAL;
+ if (len) {
+ if (audit_sockaddr(klen, kaddr))
+@@ -1840,8 +1841,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
+ msg.msg_iov = &iov;
+ iov.iov_len = size;
+ iov.iov_base = ubuf;
+- msg.msg_name = (struct sockaddr *)&address;
+- msg.msg_namelen = sizeof(address);
++ /* Save some cycles and don't copy the address if not needed */
++ msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
++ /* We assume all kernel code knows the size of sockaddr_storage */
++ msg.msg_namelen = 0;
+ if (sock->file->f_flags & O_NONBLOCK)
+ flags |= MSG_DONTWAIT;
+ err = sock_recvmsg(sock, &msg, size, flags);
+@@ -1970,7 +1973,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
+ if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
+ return -EFAULT;
+ if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
+- return -EINVAL;
++ kmsg->msg_namelen = sizeof(struct sockaddr_storage);
+ return 0;
+ }
+
+@@ -2221,16 +2224,14 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+ goto out;
+ }
+
+- /*
+- * Save the user-mode address (verify_iovec will change the
+- * kernel msghdr to use the kernel address space)
++ /* Save the user-mode address (verify_iovec will change the
++ * kernel msghdr to use the kernel address space)
+ */
+-
+ uaddr = (__force void __user *)msg_sys->msg_name;
+ uaddr_len = COMPAT_NAMELEN(msg);
+- if (MSG_CMSG_COMPAT & flags) {
++ if (MSG_CMSG_COMPAT & flags)
+ err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
+- } else
++ else
+ err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
+ if (err < 0)
+ goto out_freeiov;
+@@ -2239,6 +2240,9 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+ cmsg_ptr = (unsigned long)msg_sys->msg_control;
+ msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
+
++ /* We assume all kernel code knows the size of sockaddr_storage */
++ msg_sys->msg_namelen = 0;
++
+ if (sock->file->f_flags & O_NONBLOCK)
+ flags |= MSG_DONTWAIT;
+ err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
+diff --git a/net/tipc/socket.c b/net/tipc/socket.c
+index 6cc7ddd..dffdbea 100644
+--- a/net/tipc/socket.c
++++ b/net/tipc/socket.c
+@@ -984,9 +984,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
+ goto exit;
+ }
+
+- /* will be updated in set_orig_addr() if needed */
+- m->msg_namelen = 0;
+-
+ timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+ restart:
+
+@@ -1095,9 +1092,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
+ goto exit;
+ }
+
+- /* will be updated in set_orig_addr() if needed */
+- m->msg_namelen = 0;
+-
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
+ timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index c1f403b..01625cc 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1754,7 +1754,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
+ {
+ struct unix_sock *u = unix_sk(sk);
+
+- msg->msg_namelen = 0;
+ if (u->addr) {
+ msg->msg_namelen = u->addr->len;
+ memcpy(msg->msg_name, u->addr->name, u->addr->len);
+@@ -1778,8 +1777,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (flags&MSG_OOB)
+ goto out;
+
+- msg->msg_namelen = 0;
+-
+ err = mutex_lock_interruptible(&u->readlock);
+ if (err) {
+ err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
+@@ -1924,8 +1921,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
+ timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
+
+- msg->msg_namelen = 0;
+-
+ /* Lock the socket to prevent queue disordering
+ * while sleeps in memcpy_tomsg
+ */
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 545c08b..5adfd94 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -1662,8 +1662,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb,
+ vsk = vsock_sk(sk);
+ err = 0;
+
+- msg->msg_namelen = 0;
+-
+ lock_sock(sk);
+
+ if (sk->sk_state != SS_CONNECTED) {
+diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
+index 9d69866..687360d 100644
+--- a/net/vmw_vsock/vmci_transport.c
++++ b/net/vmw_vsock/vmci_transport.c
+@@ -1746,8 +1746,6 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,
+ if (flags & MSG_OOB || flags & MSG_ERRQUEUE)
+ return -EOPNOTSUPP;
+
+- msg->msg_namelen = 0;
+-
+ /* Retrieve the head sk_buff from the socket's receive queue. */
+ err = 0;
+ skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err);
+diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
+index 45a3ab5..7622789 100644
+--- a/net/x25/af_x25.c
++++ b/net/x25/af_x25.c
+@@ -1340,10 +1340,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (sx25) {
+ sx25->sx25_family = AF_X25;
+ sx25->sx25_addr = x25->dest_addr;
++ msg->msg_namelen = sizeof(*sx25);
+ }
+
+- msg->msg_namelen = sizeof(struct sockaddr_x25);
+-
+ x25_check_rbuf(sk);
+ rc = copied;
+ out_free_dgram: