* Re: [PATCH v3] net: Allow no-cache copy from user on transmit
From: David Miller @ 2011-04-04 16:52 UTC (permalink / raw)
To: therbert; +Cc: netdev
In-Reply-To: <BANLkTik__2JSNHXf4JBDqQPgDmMgsT9Lug@mail.gmail.com>
From: Tom Herbert <therbert@google.com>
Date: Mon, 4 Apr 2011 08:10:08 -0700
>> So it's not correct to use ARCH_HAS_NOCACHE_UACCESS to conditionalize
>> things in the networking, just make sure linux/uaccess.h is included
>> at the call sites.
>>
> Why isn't this correct? Shouldn't it be okay if linux/uaccess.h
> (asm/uaccess.h) is always included where ARCH_HAS_NOCACHE_UACCESS is
> used?
I'm simply saying to get rid of the ARCH_HAS_NOCACHE_UACCESS ifdefs
you're adding to the networking code, since linux/uaccess.h makes sure
that a nop version of the nocache routines are available always.
If you ifdef the networking bits unnecessarily, those code paths
won't get build tested in the majority of my test builds, which are
on sparc64. So I want to avoid the conditionalized compilation if
at all possible.
^ permalink raw reply
* Re: [PATCH] sched: QFQ - quick fair queue scheduler
From: Eric Dumazet @ 2011-04-04 16:34 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev, Fabio Checconi, Luigi Rizzo
In-Reply-To: <20110404083058.2f2be9f1@nehalam>
Le lundi 04 avril 2011 à 08:30 -0700, Stephen Hemminger a écrit :
> This is an implementation of the Quick Fair Queue scheduler developed
> by Fabio Checconi. The same algorithm is already implemented in ipfw
> in FreeBSD. Fabio had an earlier version developed on Linux, I just
> cleaned it up. Thanks to Eric Dumazet for testing this under load.
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
> ---
> v6.1 - add one more printk on error path
Tested again this last version on net-next-2.6 and it seems fine.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
^ permalink raw reply
* [PATCH] sched: QFQ - quick fair queue scheduler
From: Stephen Hemminger @ 2011-04-04 15:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Fabio Checconi, Luigi Rizzo
This is an implementation of the Quick Fair Queue scheduler developed
by Fabio Checconi. The same algorithm is already implemented in ipfw
in FreeBSD. Fabio had an earlier version developed on Linux, I just
cleaned it up. Thanks to Eric Dumazet for testing this under load.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
v6.1 - add one more printk on error path
include/linux/pkt_sched.h | 15
net/sched/Kconfig | 11
net/sched/Makefile | 1
net/sched/sch_qfq.c | 1137 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 1164 insertions(+)
--- a/include/linux/pkt_sched.h 2011-03-02 16:29:37.533046879 -0800
+++ b/include/linux/pkt_sched.h 2011-04-04 08:24:24.481342257 -0700
@@ -588,4 +588,19 @@ struct tc_sfb_xstats {
#define SFB_MAX_PROB 0xFFFF
+/* QFQ */
+enum {
+ TCA_QFQ_UNSPEC,
+ TCA_QFQ_WEIGHT,
+ TCA_QFQ_LMAX,
+ __TCA_QFQ_MAX
+};
+
+#define TCA_QFQ_MAX (__TCA_QFQ_MAX - 1)
+
+struct tc_qfq_stats {
+ __u32 weight;
+ __u32 lmax;
+};
+
#endif
--- a/net/sched/Kconfig 2011-03-02 16:29:37.609045663 -0800
+++ b/net/sched/Kconfig 2011-04-04 08:24:24.505342526 -0700
@@ -239,6 +239,17 @@ config NET_SCH_CHOKE
To compile this code as a module, choose M here: the
module will be called sch_choke.
+config NET_SCH_QFQ
+ tristate "Quick Fair Queueing scheduler (QFQ)"
+ help
+ Say Y here if you want to use the Quick Fair Queueing Scheduler (QFQ)
+ packet scheduling algorithm.
+
+ To compile this driver as a module, choose M here: the module
+ will be called sch_qfq.
+
+ If unsure, say N.
+
config NET_SCH_INGRESS
tristate "Ingress Qdisc"
depends on NET_CLS_ACT
--- a/net/sched/Makefile 2011-03-02 16:29:37.609045663 -0800
+++ b/net/sched/Makefile 2011-04-04 08:24:24.505342526 -0700
@@ -35,6 +35,7 @@ obj-$(CONFIG_NET_SCH_NETEM) += sch_netem
obj-$(CONFIG_NET_SCH_DRR) += sch_drr.o
obj-$(CONFIG_NET_SCH_MQPRIO) += sch_mqprio.o
obj-$(CONFIG_NET_SCH_CHOKE) += sch_choke.o
+obj-$(CONFIG_NET_SCH_QFQ) += sch_qfq.o
obj-$(CONFIG_NET_CLS_U32) += cls_u32.o
obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/net/sched/sch_qfq.c 2011-04-04 08:26:39.166845378 -0700
@@ -0,0 +1,1137 @@
+/*
+ * net/sched/sch_qfq.c Quick Fair Queueing Scheduler.
+ *
+ * Copyright (c) 2009 Fabio Checconi, Luigi Rizzo, and Paolo Valente.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/pkt_sched.h>
+#include <net/sch_generic.h>
+#include <net/pkt_sched.h>
+#include <net/pkt_cls.h>
+
+
+/* Quick Fair Queueing
+ ===================
+
+ Sources:
+
+ Fabio Checconi, Luigi Rizzo, and Paolo Valente: "QFQ: Efficient
+ Packet Scheduling with Tight Bandwidth Distribution Guarantees."
+
+ See also:
+ http://retis.sssup.it/~fabio/linux/qfq/
+ */
+
+/*
+
+ Virtual time computations.
+
+ S, F and V are all computed in fixed point arithmetic with
+ FRAC_BITS decimal bits.
+
+ QFQ_MAX_INDEX is the maximum index allowed for a group. We need
+ one bit per index.
+ QFQ_MAX_WSHIFT is the maximum power of two supported as a weight.
+
+ The layout of the bits is as below:
+
+ [ MTU_SHIFT ][ FRAC_BITS ]
+ [ MAX_INDEX ][ MIN_SLOT_SHIFT ]
+ ^.__grp->index = 0
+ *.__grp->slot_shift
+
+ where MIN_SLOT_SHIFT is derived by difference from the others.
+
+ The max group index corresponds to Lmax/w_min, where
+ Lmax=1<<MTU_SHIFT, w_min = 1 .
+ From this, and knowing how many groups (MAX_INDEX) we want,
+ we can derive the shift corresponding to each group.
+
+ Because we often need to compute
+ F = S + len/w_i and V = V + len/wsum
+ instead of storing w_i store the value
+ inv_w = (1<<FRAC_BITS)/w_i
+ so we can do F = S + len * inv_w * wsum.
+ We use W_TOT in the formulas so we can easily move between
+ static and adaptive weight sum.
+
+ The per-scheduler-instance data contain all the data structures
+ for the scheduler: bitmaps and bucket lists.
+
+ */
+
+/*
+ * Maximum number of consecutive slots occupied by backlogged classes
+ * inside a group.
+ */
+#define QFQ_MAX_SLOTS 32
+
+/*
+ * Shifts used for class<->group mapping. We allow class weights that are
+ * in the range [1, 2^MAX_WSHIFT], and we try to map each class i to the
+ * group with the smallest index that can support the L_i / r_i configured
+ * for the class.
+ *
+ * grp->index is the index of the group; and grp->slot_shift
+ * is the shift for the corresponding (scaled) sigma_i.
+ */
+#define QFQ_MAX_INDEX 19
+#define QFQ_MAX_WSHIFT 16
+
+#define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT)
+#define QFQ_MAX_WSUM (2*QFQ_MAX_WEIGHT)
+
+#define FRAC_BITS 30 /* fixed point arithmetic */
+#define ONE_FP (1UL << FRAC_BITS)
+#define IWSUM (ONE_FP/QFQ_MAX_WSUM)
+
+#define QFQ_MTU_SHIFT 11
+#define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX)
+
+/*
+ * Possible group states. These values are used as indexes for the bitmaps
+ * array of struct qfq_queue.
+ */
+enum qfq_state { ER, IR, EB, IB, QFQ_MAX_STATE };
+
+struct qfq_group;
+
+struct qfq_class {
+ struct Qdisc_class_common common;
+
+ unsigned int refcnt;
+ unsigned int filter_cnt;
+
+ struct gnet_stats_basic_packed bstats;
+ struct gnet_stats_queue qstats;
+ struct gnet_stats_rate_est rate_est;
+ struct Qdisc *qdisc;
+
+ struct hlist_node next; /* Link for the slot list. */
+ u64 S, F; /* flow timestamps (exact) */
+
+ /* group we belong to. In principle we would need the index,
+ * which is log_2(lmax/weight), but we never reference it
+ * directly, only the group.
+ */
+ struct qfq_group *grp;
+
+ /* these are copied from the flowset. */
+ u32 inv_w; /* ONE_FP/weight */
+ u32 lmax; /* Max packet size for this flow. */
+};
+
+struct qfq_group {
+ u64 S, F; /* group timestamps (approx). */
+ unsigned int slot_shift; /* Slot shift. */
+ unsigned int index; /* Group index. */
+ unsigned int front; /* Index of the front slot. */
+ unsigned long full_slots; /* non-empty slots */
+
+ /* Array of RR lists of active classes. */
+ struct hlist_head slots[QFQ_MAX_SLOTS];
+};
+
+struct qfq_sched {
+ struct tcf_proto *filter_list;
+ struct Qdisc_class_hash clhash;
+
+ u64 V; /* Precise virtual time. */
+ u32 wsum; /* weight sum */
+
+ unsigned long bitmaps[QFQ_MAX_STATE]; /* Group bitmaps. */
+ struct qfq_group groups[QFQ_MAX_INDEX + 1]; /* The groups. */
+};
+
+static struct qfq_class *qfq_find_class(struct Qdisc *sch, u32 classid)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct Qdisc_class_common *clc;
+
+ clc = qdisc_class_find(&q->clhash, classid);
+ if (clc == NULL)
+ return NULL;
+ return container_of(clc, struct qfq_class, common);
+}
+
+static void qfq_purge_queue(struct qfq_class *cl)
+{
+ unsigned int len = cl->qdisc->q.qlen;
+
+ qdisc_reset(cl->qdisc);
+ qdisc_tree_decrease_qlen(cl->qdisc, len);
+}
+
+static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = {
+ [TCA_QFQ_WEIGHT] = { .type = NLA_U32 },
+ [TCA_QFQ_LMAX] = { .type = NLA_U32 },
+};
+
+/*
+ * Calculate a flow index, given its weight and maximum packet length.
+ * index = log_2(maxlen/weight) but we need to apply the scaling.
+ * This is used only once at flow creation.
+ */
+static int qfq_calc_index(u32 inv_w, unsigned int maxlen)
+{
+ u64 slot_size = (u64)maxlen * inv_w;
+ unsigned long size_map;
+ int index = 0;
+
+ size_map = slot_size >> QFQ_MIN_SLOT_SHIFT;
+ if (!size_map)
+ goto out;
+
+ index = __fls(size_map) + 1; /* basically a log_2 */
+ index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1)));
+
+ if (index < 0)
+ index = 0;
+out:
+ pr_debug("qfq calc_index: W = %lu, L = %u, I = %d\n",
+ (unsigned long) ONE_FP/inv_w, maxlen, index);
+
+ return index;
+}
+
+static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ struct nlattr **tca, unsigned long *arg)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl = (struct qfq_class *)*arg;
+ struct nlattr *tb[TCA_QFQ_MAX + 1];
+ u32 weight, lmax, inv_w;
+ int i, err;
+
+ if (tca[TCA_OPTIONS] == NULL) {
+ pr_notice("qfq: no options\n");
+ return -EINVAL;
+ }
+
+ err = nla_parse_nested(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS], qfq_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[TCA_QFQ_WEIGHT]) {
+ weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]);
+ if (!weight || weight > (1UL << QFQ_MAX_WSHIFT)) {
+ pr_notice("qfq: invalid weight %u\n", weight);
+ return -EINVAL;
+ }
+ } else
+ weight = 1;
+
+ inv_w = ONE_FP / weight;
+ weight = ONE_FP / inv_w;
+ if (q->wsum + weight > QFQ_MAX_WSUM) {
+ pr_notice("qfq: total weight out of range (%u + %u)\n",
+ weight, q->wsum);
+ return -EINVAL;
+ }
+
+ if (tb[TCA_QFQ_LMAX]) {
+ lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
+ if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) {
+ pr_notice("qfq: invalid max length %u\n", lmax);
+ return -EINVAL;
+ }
+ } else
+ lmax = 1UL << QFQ_MTU_SHIFT;
+
+ if (cl != NULL) {
+ if (tca[TCA_RATE]) {
+ err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
+ qdisc_root_sleeping_lock(sch),
+ tca[TCA_RATE]);
+ if (err)
+ return err;
+ }
+
+ sch_tree_lock(sch);
+ if (tb[TCA_QFQ_WEIGHT]) {
+ q->wsum = weight - ONE_FP / cl->inv_w;
+ cl->inv_w = inv_w;
+ }
+ sch_tree_unlock(sch);
+
+ return 0;
+ }
+
+ cl = kzalloc(sizeof(struct qfq_class), GFP_KERNEL);
+ if (cl == NULL)
+ return -ENOBUFS;
+
+ cl->refcnt = 1;
+ cl->common.classid = classid;
+ cl->lmax = lmax;
+ cl->inv_w = inv_w;
+ i = qfq_calc_index(cl->inv_w, cl->lmax);
+
+ cl->grp = &q->groups[i];
+ q->wsum += weight;
+
+ cl->qdisc = qdisc_create_dflt(sch->dev_queue,
+ &pfifo_qdisc_ops, classid);
+ if (cl->qdisc == NULL)
+ cl->qdisc = &noop_qdisc;
+
+ if (tca[TCA_RATE]) {
+ err = gen_new_estimator(&cl->bstats, &cl->rate_est,
+ qdisc_root_sleeping_lock(sch),
+ tca[TCA_RATE]);
+ if (err) {
+ qdisc_destroy(cl->qdisc);
+ kfree(cl);
+ return err;
+ }
+ }
+
+ sch_tree_lock(sch);
+ qdisc_class_hash_insert(&q->clhash, &cl->common);
+ sch_tree_unlock(sch);
+
+ qdisc_class_hash_grow(sch, &q->clhash);
+
+ *arg = (unsigned long)cl;
+ return 0;
+}
+
+static void qfq_destroy_class(struct Qdisc *sch, struct qfq_class *cl)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+
+ if (cl->inv_w) {
+ q->wsum -= ONE_FP / cl->inv_w;
+ cl->inv_w = 0;
+ }
+
+ gen_kill_estimator(&cl->bstats, &cl->rate_est);
+ qdisc_destroy(cl->qdisc);
+ kfree(cl);
+}
+
+static int qfq_delete_class(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ if (cl->filter_cnt > 0)
+ return -EBUSY;
+
+ sch_tree_lock(sch);
+
+ qfq_purge_queue(cl);
+ qdisc_class_hash_remove(&q->clhash, &cl->common);
+
+ BUG_ON(--cl->refcnt == 0);
+ /*
+ * This shouldn't happen: we "hold" one cops->get() when called
+ * from tc_ctl_tclass; the destroy method is done from cops->put().
+ */
+
+ sch_tree_unlock(sch);
+ return 0;
+}
+
+static unsigned long qfq_get_class(struct Qdisc *sch, u32 classid)
+{
+ struct qfq_class *cl = qfq_find_class(sch, classid);
+
+ if (cl != NULL)
+ cl->refcnt++;
+
+ return (unsigned long)cl;
+}
+
+static void qfq_put_class(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ if (--cl->refcnt == 0)
+ qfq_destroy_class(sch, cl);
+}
+
+static struct tcf_proto **qfq_tcf_chain(struct Qdisc *sch, unsigned long cl)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+
+ if (cl)
+ return NULL;
+
+ return &q->filter_list;
+}
+
+static unsigned long qfq_bind_tcf(struct Qdisc *sch, unsigned long parent,
+ u32 classid)
+{
+ struct qfq_class *cl = qfq_find_class(sch, classid);
+
+ if (cl != NULL)
+ cl->filter_cnt++;
+
+ return (unsigned long)cl;
+}
+
+static void qfq_unbind_tcf(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ cl->filter_cnt--;
+}
+
+static int qfq_graft_class(struct Qdisc *sch, unsigned long arg,
+ struct Qdisc *new, struct Qdisc **old)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ if (new == NULL) {
+ new = qdisc_create_dflt(sch->dev_queue,
+ &pfifo_qdisc_ops, cl->common.classid);
+ if (new == NULL)
+ new = &noop_qdisc;
+ }
+
+ sch_tree_lock(sch);
+ qfq_purge_queue(cl);
+ *old = cl->qdisc;
+ cl->qdisc = new;
+ sch_tree_unlock(sch);
+ return 0;
+}
+
+static struct Qdisc *qfq_class_leaf(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ return cl->qdisc;
+}
+
+static int qfq_dump_class(struct Qdisc *sch, unsigned long arg,
+ struct sk_buff *skb, struct tcmsg *tcm)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+ struct nlattr *nest;
+
+ tcm->tcm_parent = TC_H_ROOT;
+ tcm->tcm_handle = cl->common.classid;
+ tcm->tcm_info = cl->qdisc->handle;
+
+ nest = nla_nest_start(skb, TCA_OPTIONS);
+ if (nest == NULL)
+ goto nla_put_failure;
+ NLA_PUT_U32(skb, TCA_QFQ_WEIGHT, ONE_FP/cl->inv_w);
+ NLA_PUT_U32(skb, TCA_QFQ_LMAX, cl->lmax);
+ return nla_nest_end(skb, nest);
+
+nla_put_failure:
+ nla_nest_cancel(skb, nest);
+ return -EMSGSIZE;
+}
+
+static int qfq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
+ struct gnet_dump *d)
+{
+ struct qfq_class *cl = (struct qfq_class *)arg;
+ struct tc_qfq_stats xstats;
+
+ memset(&xstats, 0, sizeof(xstats));
+ cl->qdisc->qstats.qlen = cl->qdisc->q.qlen;
+
+ xstats.weight = ONE_FP/cl->inv_w;
+ xstats.lmax = cl->lmax;
+
+ if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
+ gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 ||
+ gnet_stats_copy_queue(d, &cl->qdisc->qstats) < 0)
+ return -1;
+
+ return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
+}
+
+static void qfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl;
+ struct hlist_node *n;
+ unsigned int i;
+
+ if (arg->stop)
+ return;
+
+ for (i = 0; i < q->clhash.hashsize; i++) {
+ hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode) {
+ if (arg->count < arg->skip) {
+ arg->count++;
+ continue;
+ }
+ if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
+ arg->stop = 1;
+ return;
+ }
+ arg->count++;
+ }
+ }
+}
+
+static struct qfq_class *qfq_classify(struct sk_buff *skb, struct Qdisc *sch,
+ int *qerr)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl;
+ struct tcf_result res;
+ int result;
+
+ if (TC_H_MAJ(skb->priority ^ sch->handle) == 0) {
+ pr_debug("qfq_classify: found %d\n", skb->priority);
+ cl = qfq_find_class(sch, skb->priority);
+ if (cl != NULL)
+ return cl;
+ }
+
+ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
+ result = tc_classify(skb, q->filter_list, &res);
+ if (result >= 0) {
+#ifdef CONFIG_NET_CLS_ACT
+ switch (result) {
+ case TC_ACT_QUEUED:
+ case TC_ACT_STOLEN:
+ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
+ case TC_ACT_SHOT:
+ return NULL;
+ }
+#endif
+ cl = (struct qfq_class *)res.class;
+ if (cl == NULL)
+ cl = qfq_find_class(sch, res.classid);
+ return cl;
+ }
+
+ return NULL;
+}
+
+/* Generic comparison function, handling wraparound. */
+static inline int qfq_gt(u64 a, u64 b)
+{
+ return (s64)(a - b) > 0;
+}
+
+/* Round a precise timestamp to its slotted value. */
+static inline u64 qfq_round_down(u64 ts, unsigned int shift)
+{
+ return ts & ~((1ULL << shift) - 1);
+}
+
+/* return the pointer to the group with lowest index in the bitmap */
+static inline struct qfq_group *qfq_ffs(struct qfq_sched *q,
+ unsigned long bitmap)
+{
+ int index = __ffs(bitmap);
+ return &q->groups[index];
+}
+/* Calculate a mask to mimic what would be ffs_from(). */
+static inline unsigned long mask_from(unsigned long bitmap, int from)
+{
+ return bitmap & ~((1UL << from) - 1);
+}
+
+/*
+ * The state computation relies on ER=0, IR=1, EB=2, IB=3
+ * First compute eligibility comparing grp->S, q->V,
+ * then check if someone is blocking us and possibly add EB
+ */
+static int qfq_calc_state(struct qfq_sched *q, const struct qfq_group *grp)
+{
+ /* if S > V we are not eligible */
+ unsigned int state = qfq_gt(grp->S, q->V);
+ unsigned long mask = mask_from(q->bitmaps[ER], grp->index);
+ struct qfq_group *next;
+
+ if (mask) {
+ next = qfq_ffs(q, mask);
+ if (qfq_gt(grp->F, next->F))
+ state |= EB;
+ }
+
+ return state;
+}
+
+
+/*
+ * In principle
+ * q->bitmaps[dst] |= q->bitmaps[src] & mask;
+ * q->bitmaps[src] &= ~mask;
+ * but we should make sure that src != dst
+ */
+static inline void qfq_move_groups(struct qfq_sched *q, unsigned long mask,
+ int src, int dst)
+{
+ q->bitmaps[dst] |= q->bitmaps[src] & mask;
+ q->bitmaps[src] &= ~mask;
+}
+
+static void qfq_unblock_groups(struct qfq_sched *q, int index, u64 old_F)
+{
+ unsigned long mask = mask_from(q->bitmaps[ER], index + 1);
+ struct qfq_group *next;
+
+ if (mask) {
+ next = qfq_ffs(q, mask);
+ if (!qfq_gt(next->F, old_F))
+ return;
+ }
+
+ mask = (1UL << index) - 1;
+ qfq_move_groups(q, mask, EB, ER);
+ qfq_move_groups(q, mask, IB, IR);
+}
+
+/*
+ * perhaps
+ *
+ old_V ^= q->V;
+ old_V >>= QFQ_MIN_SLOT_SHIFT;
+ if (old_V) {
+ ...
+ }
+ *
+ */
+static void qfq_make_eligible(struct qfq_sched *q, u64 old_V)
+{
+ unsigned long vslot = q->V >> QFQ_MIN_SLOT_SHIFT;
+ unsigned long old_vslot = old_V >> QFQ_MIN_SLOT_SHIFT;
+
+ if (vslot != old_vslot) {
+ unsigned long mask = (1UL << fls(vslot ^ old_vslot)) - 1;
+ qfq_move_groups(q, mask, IR, ER);
+ qfq_move_groups(q, mask, IB, EB);
+ }
+}
+
+
+/*
+ * XXX we should make sure that slot becomes less than 32.
+ * This is guaranteed by the input values.
+ * roundedS is always cl->S rounded on grp->slot_shift bits.
+ */
+static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl,
+ u64 roundedS)
+{
+ u64 slot = (roundedS - grp->S) >> grp->slot_shift;
+ unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS;
+
+ hlist_add_head(&cl->next, &grp->slots[i]);
+ __set_bit(slot, &grp->full_slots);
+}
+
+/* Maybe introduce hlist_first_entry?? */
+static struct qfq_class *qfq_slot_head(struct qfq_group *grp)
+{
+ return hlist_entry(grp->slots[grp->front].first,
+ struct qfq_class, next);
+}
+
+/*
+ * remove the entry from the slot
+ */
+static void qfq_front_slot_remove(struct qfq_group *grp)
+{
+ struct qfq_class *cl = qfq_slot_head(grp);
+
+ BUG_ON(!cl);
+ hlist_del(&cl->next);
+ if (hlist_empty(&grp->slots[grp->front]))
+ __clear_bit(0, &grp->full_slots);
+}
+
+/*
+ * Returns the first full queue in a group. As a side effect,
+ * adjust the bucket list so the first non-empty bucket is at
+ * position 0 in full_slots.
+ */
+static struct qfq_class *qfq_slot_scan(struct qfq_group *grp)
+{
+ unsigned int i;
+
+ pr_debug("qfq slot_scan: grp %u full %#lx\n",
+ grp->index, grp->full_slots);
+
+ if (grp->full_slots == 0)
+ return NULL;
+
+ i = __ffs(grp->full_slots); /* zero based */
+ if (i > 0) {
+ grp->front = (grp->front + i) % QFQ_MAX_SLOTS;
+ grp->full_slots >>= i;
+ }
+
+ return qfq_slot_head(grp);
+}
+
+/*
+ * adjust the bucket list. When the start time of a group decreases,
+ * we move the index down (modulo QFQ_MAX_SLOTS) so we don't need to
+ * move the objects. The mask of occupied slots must be shifted
+ * because we use ffs() to find the first non-empty slot.
+ * This covers decreases in the group's start time, but what about
+ * increases of the start time ?
+ * Here too we should make sure that i is less than 32
+ */
+static void qfq_slot_rotate(struct qfq_group *grp, u64 roundedS)
+{
+ unsigned int i = (grp->S - roundedS) >> grp->slot_shift;
+
+ grp->full_slots <<= i;
+ grp->front = (grp->front - i) % QFQ_MAX_SLOTS;
+}
+
+static void qfq_update_eligible(struct qfq_sched *q, u64 old_V)
+{
+ struct qfq_group *grp;
+ unsigned long ineligible;
+
+ ineligible = q->bitmaps[IR] | q->bitmaps[IB];
+ if (ineligible) {
+ if (!q->bitmaps[ER]) {
+ grp = qfq_ffs(q, ineligible);
+ if (qfq_gt(grp->S, q->V))
+ q->V = grp->S;
+ }
+ qfq_make_eligible(q, old_V);
+ }
+}
+
+/* What is length of next packet in queue (0 if queue is empty) */
+static unsigned int qdisc_peek_len(struct Qdisc *sch)
+{
+ struct sk_buff *skb;
+
+ skb = sch->ops->peek(sch);
+ return skb ? qdisc_pkt_len(skb) : 0;
+}
+
+/*
+ * Updates the class, returns true if also the group needs to be updated.
+ */
+static bool qfq_update_class(struct qfq_group *grp, struct qfq_class *cl)
+{
+ unsigned int len = qdisc_peek_len(cl->qdisc);
+
+ cl->S = cl->F;
+ if (!len)
+ qfq_front_slot_remove(grp); /* queue is empty */
+ else {
+ u64 roundedS;
+
+ cl->F = cl->S + (u64)len * cl->inv_w;
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ if (roundedS == grp->S)
+ return false;
+
+ qfq_front_slot_remove(grp);
+ qfq_slot_insert(grp, cl, roundedS);
+ }
+
+ return true;
+}
+
+static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ struct qfq_class *cl;
+ struct sk_buff *skb;
+ unsigned int len;
+ u64 old_V;
+
+ if (!q->bitmaps[ER])
+ return NULL;
+
+ grp = qfq_ffs(q, q->bitmaps[ER]);
+
+ cl = qfq_slot_head(grp);
+ skb = qdisc_dequeue_peeked(cl->qdisc);
+ if (!skb) {
+ WARN_ONCE(1, "qfq_dequeue: non-workconserving leaf\n");
+ return NULL;
+ }
+
+ sch->q.qlen--;
+ qdisc_bstats_update(sch, skb);
+
+ old_V = q->V;
+ len = qdisc_pkt_len(skb);
+ q->V += (u64)len * IWSUM;
+ pr_debug("qfq dequeue: len %u F %lld now %lld\n",
+ len, (unsigned long long) cl->F, (unsigned long long) q->V);
+
+ if (qfq_update_class(grp, cl)) {
+ u64 old_F = grp->F;
+
+ cl = qfq_slot_scan(grp);
+ if (!cl)
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ else {
+ u64 roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ unsigned int s;
+
+ if (grp->S == roundedS)
+ goto skip_unblock;
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ }
+
+ qfq_unblock_groups(q, grp->index, old_F);
+ }
+
+skip_unblock:
+ qfq_update_eligible(q, old_V);
+
+ return skb;
+}
+
+/*
+ * Assign a reasonable start time for a new flow k in group i.
+ * Admissible values for \hat(F) are multiples of \sigma_i
+ * no greater than V+\sigma_i . Larger values mean that
+ * we had a wraparound so we consider the timestamp to be stale.
+ *
+ * If F is not stale and F >= V then we set S = F.
+ * Otherwise we should assign S = V, but this may violate
+ * the ordering in ER. So, if we have groups in ER, set S to
+ * the F_j of the first group j which would be blocking us.
+ * We are guaranteed not to move S backward because
+ * otherwise our group i would still be blocked.
+ */
+static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
+{
+ unsigned long mask;
+ uint32_t limit, roundedF;
+ int slot_shift = cl->grp->slot_shift;
+
+ roundedF = qfq_round_down(cl->F, slot_shift);
+ limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift);
+
+ if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) {
+ /* timestamp was stale */
+ mask = mask_from(q->bitmaps[ER], cl->grp->index);
+ if (mask) {
+ struct qfq_group *next = qfq_ffs(q, mask);
+ if (qfq_gt(roundedF, next->F)) {
+ cl->S = next->F;
+ return;
+ }
+ }
+ cl->S = q->V;
+ } else /* timestamp is not stale */
+ cl->S = cl->F;
+}
+
+static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ struct qfq_class *cl;
+ int err;
+ u64 roundedS;
+ int s;
+
+ cl = qfq_classify(skb, sch, &err);
+ if (cl == NULL) {
+ if (err & __NET_XMIT_BYPASS)
+ sch->qstats.drops++;
+ kfree_skb(skb);
+ return err;
+ }
+ pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid);
+
+ err = qdisc_enqueue(skb, cl->qdisc);
+ if (unlikely(err != NET_XMIT_SUCCESS)) {
+ pr_debug("qfq_enqueue: enqueue failed %d\n", err);
+ if (net_xmit_drop_count(err)) {
+ cl->qstats.drops++;
+ sch->qstats.drops++;
+ }
+ return err;
+ }
+
+ bstats_update(&cl->bstats, skb);
+ ++sch->q.qlen;
+
+ /* If the new skb is not the head of queue, then done here. */
+ if (cl->qdisc->q.qlen != 1)
+ return err;
+
+ /* If reach this point, queue q was idle */
+ grp = cl->grp;
+ qfq_update_start(q, cl);
+
+ /* compute new finish time and rounded start. */
+ cl->F = cl->S + (u64)qdisc_pkt_len(skb) * cl->inv_w;
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+
+ /*
+ * insert cl in the correct bucket.
+ * If cl->S >= grp->S we don't need to adjust the
+ * bucket list and simply go to the insertion phase.
+ * Otherwise grp->S is decreasing, we must make room
+ * in the bucket list, and also recompute the group state.
+ * Finally, if there were no flows in this group and nobody
+ * was in ER make sure to adjust V.
+ */
+ if (grp->full_slots) {
+ if (!qfq_gt(grp->S, cl->S))
+ goto skip_update;
+
+ /* create a slot for this cl->S */
+ qfq_slot_rotate(grp, roundedS);
+ /* group was surely ineligible, remove */
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+ } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
+ q->V = roundedS;
+
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+
+ pr_debug("qfq enqueue: new state %d %#lx S %lld F %lld V %lld\n",
+ s, q->bitmaps[s],
+ (unsigned long long) cl->S,
+ (unsigned long long) cl->F,
+ (unsigned long long) q->V);
+
+skip_update:
+ qfq_slot_insert(grp, cl, roundedS);
+
+ return err;
+}
+
+
+static void qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
+ struct qfq_class *cl)
+{
+ unsigned int i, offset;
+ u64 roundedS;
+
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ offset = (roundedS - grp->S) >> grp->slot_shift;
+ i = (grp->front + offset) % QFQ_MAX_SLOTS;
+
+ hlist_del(&cl->next);
+ if (hlist_empty(&grp->slots[i]))
+ __clear_bit(offset, &grp->full_slots);
+}
+
+/*
+ * called to forcibly destroy a queue.
+ * If the queue is not in the front bucket, or if it has
+ * other queues in the front bucket, we can simply remove
+ * the queue with no other side effects.
+ * Otherwise we must propagate the event up.
+ */
+static void qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl)
+{
+ struct qfq_group *grp = cl->grp;
+ unsigned long mask;
+ u64 roundedS;
+ int s;
+
+ cl->F = cl->S;
+ qfq_slot_remove(q, grp, cl);
+
+ if (!grp->full_slots) {
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[EB]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+
+ if (test_bit(grp->index, &q->bitmaps[ER]) &&
+ !(q->bitmaps[ER] & ~((1UL << grp->index) - 1))) {
+ mask = q->bitmaps[ER] & ((1UL << grp->index) - 1);
+ if (mask)
+ mask = ~((1UL << __fls(mask)) - 1);
+ else
+ mask = ~0UL;
+ qfq_move_groups(q, mask, EB, ER);
+ qfq_move_groups(q, mask, IB, IR);
+ }
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ } else if (hlist_empty(&grp->slots[grp->front])) {
+ cl = qfq_slot_scan(grp);
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ if (grp->S != roundedS) {
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[EB]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ }
+ }
+
+ qfq_update_eligible(q, q->V);
+}
+
+static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl = (struct qfq_class *)arg;
+
+ if (cl->qdisc->q.qlen == 0)
+ qfq_deactivate_class(q, cl);
+}
+
+static unsigned int qfq_drop(struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ unsigned int i, j, len;
+
+ for (i = 0; i <= QFQ_MAX_INDEX; i++) {
+ grp = &q->groups[i];
+ for (j = 0; j < QFQ_MAX_SLOTS; j++) {
+ struct qfq_class *cl;
+ struct hlist_node *n;
+
+ hlist_for_each_entry(cl, n, &grp->slots[j], next) {
+
+ if (!cl->qdisc->ops->drop)
+ continue;
+
+ len = cl->qdisc->ops->drop(cl->qdisc);
+ if (len > 0) {
+ sch->q.qlen--;
+ if (!cl->qdisc->q.qlen)
+ qfq_deactivate_class(q, cl);
+
+ return len;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ int i, j, err;
+
+ err = qdisc_class_hash_init(&q->clhash);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i <= QFQ_MAX_INDEX; i++) {
+ grp = &q->groups[i];
+ grp->index = i;
+ grp->slot_shift = QFQ_MTU_SHIFT + FRAC_BITS
+ - (QFQ_MAX_INDEX - i);
+ for (j = 0; j < QFQ_MAX_SLOTS; j++)
+ INIT_HLIST_HEAD(&grp->slots[j]);
+ }
+
+ return 0;
+}
+
+static void qfq_reset_qdisc(struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_group *grp;
+ struct qfq_class *cl;
+ struct hlist_node *n, *tmp;
+ unsigned int i, j;
+
+ for (i = 0; i <= QFQ_MAX_INDEX; i++) {
+ grp = &q->groups[i];
+ for (j = 0; j < QFQ_MAX_SLOTS; j++) {
+ hlist_for_each_entry_safe(cl, n, tmp,
+ &grp->slots[j], next) {
+ qfq_deactivate_class(q, cl);
+ }
+ }
+ }
+
+ for (i = 0; i < q->clhash.hashsize; i++) {
+ hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode)
+ qdisc_reset(cl->qdisc);
+ }
+ sch->q.qlen = 0;
+}
+
+static void qfq_destroy_qdisc(struct Qdisc *sch)
+{
+ struct qfq_sched *q = qdisc_priv(sch);
+ struct qfq_class *cl;
+ struct hlist_node *n, *next;
+ unsigned int i;
+
+ tcf_destroy_chain(&q->filter_list);
+
+ for (i = 0; i < q->clhash.hashsize; i++) {
+ hlist_for_each_entry_safe(cl, n, next, &q->clhash.hash[i],
+ common.hnode) {
+ qfq_destroy_class(sch, cl);
+ }
+ }
+ qdisc_class_hash_destroy(&q->clhash);
+}
+
+static const struct Qdisc_class_ops qfq_class_ops = {
+ .change = qfq_change_class,
+ .delete = qfq_delete_class,
+ .get = qfq_get_class,
+ .put = qfq_put_class,
+ .tcf_chain = qfq_tcf_chain,
+ .bind_tcf = qfq_bind_tcf,
+ .unbind_tcf = qfq_unbind_tcf,
+ .graft = qfq_graft_class,
+ .leaf = qfq_class_leaf,
+ .qlen_notify = qfq_qlen_notify,
+ .dump = qfq_dump_class,
+ .dump_stats = qfq_dump_class_stats,
+ .walk = qfq_walk,
+};
+
+static struct Qdisc_ops qfq_qdisc_ops __read_mostly = {
+ .cl_ops = &qfq_class_ops,
+ .id = "qfq",
+ .priv_size = sizeof(struct qfq_sched),
+ .enqueue = qfq_enqueue,
+ .dequeue = qfq_dequeue,
+ .peek = qdisc_peek_dequeued,
+ .drop = qfq_drop,
+ .init = qfq_init_qdisc,
+ .reset = qfq_reset_qdisc,
+ .destroy = qfq_destroy_qdisc,
+ .owner = THIS_MODULE,
+};
+
+static int __init qfq_init(void)
+{
+ return register_qdisc(&qfq_qdisc_ops);
+}
+
+static void __exit qfq_exit(void)
+{
+ unregister_qdisc(&qfq_qdisc_ops);
+}
+
+module_init(qfq_init);
+module_exit(qfq_exit);
+MODULE_LICENSE("GPL");
^ permalink raw reply
* Re: [PATCH v3] net: Allow no-cache copy from user on transmit
From: Tom Herbert @ 2011-04-04 15:10 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20110403.222341.149838774.davem@davemloft.net>
> Actually, I'm sorry, I have to kick this back to you again Tom.
>
I don't think I see the problem. Does this still fail sparc compilation?
> The original problem is that "linux/uaccess.h" has not been included
> in the spot where you try to invoke the nocache copies.
>
So I added include of linux/uaccess.h to net/sock.h.
> linux/uaccess.h, when ARCH_HAS_NOCACHE_UACCESS is defined, provides
> dummy routines.
>
I assume you mean "is not defined"?
> So it's not correct to use ARCH_HAS_NOCACHE_UACCESS to conditionalize
> things in the networking, just make sure linux/uaccess.h is included
> at the call sites.
>
Why isn't this correct? Shouldn't it be okay if linux/uaccess.h
(asm/uaccess.h) is always included where ARCH_HAS_NOCACHE_UACCESS is
used?
^ permalink raw reply
* Re: [PATCH net-next-2.6] netfilter: get rid of atomic ops in fast path
From: Patrick McHardy @ 2011-04-04 15:05 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, Netfilter Development Mailinglist, netdev,
Jan Engelhardt
In-Reply-To: <1301836523.2837.159.camel@edumazet-laptop>
On 03.04.2011 15:15, Eric Dumazet wrote:
> We currently use a percpu spinlock to 'protect' rule bytes/packets
> counters, after various attempts to use RCU instead.
>
> Lately we added a seqlock so that get_counters() can run without
> blocking BH or 'writers'. But we really only need the seqcount in it.
>
> Spinlock itself is only locked by the current/owner cpu, so we can
> remove it completely.
>
> This cleanups api, using correct 'writer' vs 'reader' semantic.
>
> At replace time, the get_counters() call makes sure all cpus are done
> using the old table.
Applied, thanks Eric.
^ permalink raw reply
* Re: [PATCH] net: Fix dev dev_ethtool_get_rx_csum() for forced NETIF_F_RXCSUM
From: Ben Hutchings @ 2011-04-04 14:54 UTC (permalink / raw)
To: Michał Mirosław; +Cc: David Miller, netdev
In-Reply-To: <20110404141443.GA26686@rere.qmqm.pl>
On Mon, 2011-04-04 at 16:14 +0200, Michał Mirosław wrote:
> On Fri, Apr 01, 2011 at 08:23:35PM -0700, David Miller wrote:
> > From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> > Date: Thu, 31 Mar 2011 11:58:08 +0200 (CEST)
> > > dev_ethtool_get_rx_csum() won't report rx checksumming when it's not
> > > changeable and driver is converted to hw_features and friends. Fix this.
> > >
> > > (dev->hw_features & NETIF_F_RXCSUM) check is dropped - if the
> > > ethtool_ops->get_rx_csum is set, then driver is not coverted, yet.
> > >
> > > Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> > Applied, thanks.
>
> I noticed this didn't get into your net-next tree (it's only in net).
> This impacts the hw_features conversions that are in net-next.
>
> BTW, what's the policy for this kind of patches? I send them relative
> to net-next normally and note if this is also for -rc/stable - is this
> The Good Way(tm)?
If you want a change to be included in the upcoming release, it must be
applied initially to net-2.6; therefore it must be based on net-2.6.
David will periodically merge net-2.6 into net-next-2.6. You can
probably do a test merge yourself if you want to see what the result
will be.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH] net: Fix dev dev_ethtool_get_rx_csum() for forced NETIF_F_RXCSUM
From: Michał Mirosław @ 2011-04-04 14:14 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20110401.202335.260089653.davem@davemloft.net>
On Fri, Apr 01, 2011 at 08:23:35PM -0700, David Miller wrote:
> From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Date: Thu, 31 Mar 2011 11:58:08 +0200 (CEST)
> > dev_ethtool_get_rx_csum() won't report rx checksumming when it's not
> > changeable and driver is converted to hw_features and friends. Fix this.
> >
> > (dev->hw_features & NETIF_F_RXCSUM) check is dropped - if the
> > ethtool_ops->get_rx_csum is set, then driver is not coverted, yet.
> >
> > Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Applied, thanks.
I noticed this didn't get into your net-next tree (it's only in net).
This impacts the hw_features conversions that are in net-next.
BTW, what's the policy for this kind of patches? I send them relative
to net-next normally and note if this is also for -rc/stable - is this
The Good Way(tm)?
Best Regards,
Michał Mirosław
^ permalink raw reply
* Re: [PATCH] netfilter: Fix build failure when ipv6 but xt_tproxy is built in
From: Patrick McHardy @ 2011-04-04 13:54 UTC (permalink / raw)
To: David Miller; +Cc: rostedt, linux-kernel, hidden, akpm, netfilter-devel, netdev
In-Reply-To: <20110329.223536.245392030.davem@davemloft.net>
On 30.03.2011 07:35, David Miller wrote:
> From: Steven Rostedt <rostedt@goodmis.org>
> Date: Tue, 29 Mar 2011 22:13:19 -0400
>
>> While running ktest.pl doing ranconfigs, the following build error
>> occurred:
>
> Is sending netfilter patches to the explicitly listed maintainer in
> MAINTAINERS too much to ask Stephen? :-/
>
> CC:'d
>
>>
>> net/built-in.o: In function `tproxy_tg6_v1':
>> /home/rostedt/work/autotest/nobackup/linux-test.git/net/netfilter/xt_TPROXY.c:288: undefined reference to `ipv6_find_hdr'
>>
>> This happened because the xt_TPROXY code was compiled into the kernel
>> proper, but the ipv6 netfilter was compiled as a module. The fix is to
>> only enter the code that calls ipv6_find_hdr if ipv6 netfilter is
>> compiled into the kernel, or if it is a module, so is the xt_TPROXY
>> code.
I don't think this is a good fix for the problem since it may lead to
the confusing situation that both TPROXY and ip6tables are enabled,
but TPROXY has no IPv6 support.
I think we should solve this by either adding a Kconfig dependency
on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n) or using ipv6_skip_exthdr()
instead of ipv6_find_hdr().
Krisztian, what do you think?
>>
>> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
>>
>> diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
>> index dcfd57e..5915f94 100644
>> --- a/net/netfilter/xt_TPROXY.c
>> +++ b/net/netfilter/xt_TPROXY.c
>> @@ -22,7 +22,13 @@
>>
>> #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
>>
>> -#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
>> +/*
>> + * Only include the following if ip6 tables is compiled in
>> + * the kernel, or it is a module and this code is also a module.
>> + */
>> +#if defined(CONFIG_IP6_NF_IPTABLES) || \
>> + (defined(CONFIG_IP6_NF_IPTABLES_MODULE) && \
>> + defined(CONFIG_NETFILTER_XT_TARGET_TPROXY_MODULE))
>> #define XT_TPROXY_HAVE_IPV6 1
>> #include <net/if_inet6.h>
>> #include <net/addrconf.h>
>>
>>
>
^ permalink raw reply
* Re: [PATCH] IPVS Bug, Null ptr in ip_vs_ctl.c ip_vs_genl_dump_daemons().
From: Patrick McHardy @ 2011-04-04 13:28 UTC (permalink / raw)
To: Simon Horman
Cc: lvs-devel, netdev, netfilter-devel, netfilter, Hans Schillstrom,
Julian Anastasov, Hans Schillstrom
In-Reply-To: <1301535135-4288-2-git-send-email-horms@verge.net.au>
On 31.03.2011 03:32, Simon Horman wrote:
> From: Hans Schillstrom <hans.schillstrom@ericsson.com>
>
> ipvsadm -ln --daemon will trigger a Null pointer exception because
> ip_vs_genl_dump_daemons() uses skb_net() instead of skb_sknet().
>
> To prevent others from NULL ptr a check is made in ip_vs.h skb_net().
>
Applied, thanks.
^ permalink raw reply
* Re: [GIT PULL nf-2.6] IPVS
From: Patrick McHardy @ 2011-04-04 13:27 UTC (permalink / raw)
To: Simon Horman
Cc: lvs-devel, netdev, netfilter-devel, netfilter, Hans Schillstrom,
Julian Anastasov
In-Reply-To: <1301535135-4288-1-git-send-email-horms@verge.net.au>
On 31.03.2011 03:32, Simon Horman wrote:
> Hi Patrick,
>
> please consider pulling
> git://git.kernel.org/pub/scm/linux/kernel/git/horms/lvs-test-2.6.git for-patrick
> to get the following fix from Hans.
>
> I have based this patch on net-2.6/master as nf-2.6/master seems a little
> out of date (i.e. pre 2.6.39-rc1). Please let me know if you would
> prefer me to use a different base. Alternatively, feel free to apply
> the single patch by hand.
I'll apply this by hand to avoid possible unnecessary merge commits.
I've also updated nf-2.6.git to net-2.6.git.
^ permalink raw reply
* Re: [PATCH] netfilter: h323: bug in parsing of ASN1 SEQOF field
From: Patrick McHardy @ 2011-04-04 13:24 UTC (permalink / raw)
To: David Miller
Cc: dsterba, netdev, linux-kernel, stable,
Netfilter Development Mailinglist
In-Reply-To: <20110322.193349.102533280.davem@davemloft.net>
On 23.03.2011 03:33, David Miller wrote:
> From: David Sterba <dsterba@suse.cz>
> Date: Tue, 22 Mar 2011 12:55:29 +0100
>
>> Static analyzer of clang found a dead store which appears to be a bug in
>> reading count of items in SEQOF field, only the lower byte of word is
>> stored. This may lead to corrupted read and communication shutdown.
>>
>> The bug has been in the module since it's first inclusion into linux
>> kernel.
>>
>> Signed-off-by: David Sterba <dsterba@suse.cz>
>
> Please send netfilter patches to the listed netfilter maintainer
> and appropriate mailing lists. I've added them to the CC:
>
> Otherwise your patch will not be looked at by the right people.
>
>> CC: David Miller <davem@davemloft.net>
>> CC: netdev@vger.kernel.org
>> CC: stable@kernel.org
>> ---
>> net/netfilter/nf_conntrack_h323_asn1.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c
>> index 8678823..bcd5ed6 100644
>> --- a/net/netfilter/nf_conntrack_h323_asn1.c
>> +++ b/net/netfilter/nf_conntrack_h323_asn1.c
>> @@ -631,7 +631,7 @@ static int decode_seqof(bitstr_t *bs, const struct field_t *f,
>> CHECK_BOUND(bs, 2);
>> count = *bs->cur++;
>> count <<= 8;
>> - count = *bs->cur++;
>> + count += *bs->cur++;
>> break;
This looks correct to me. The problem is without practical consequence
though, the largest amount of sequence-of members we parse is 30.
Applied, thanks.
^ permalink raw reply
* Re: connector: convert to synchronous netlink message processing
From: Patrick McHardy @ 2011-04-04 12:47 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: Linux Netdev List
In-Reply-To: <20110330133913.GA9425@ioremap.net>
On 30.03.2011 15:39, Evgeniy Polyakov wrote:
> Hi Patrick
>
> On Mon, Mar 28, 2011 at 08:39:36PM +0200, Patrick McHardy (kaber@trash.net) wrote:
>> This patch fixes up connector to work properly with the recent
>> netlink changes that require synchronous netlink message processing.
>>
>> The patch is so far only compile tested since I'm still looking
>> for a good way to test it. If you could point me to some software
>> using the proc events that would be appreciated.
>
> There is test module in Documentation/connector/ and/or samples/ which I
> used for tests. It was quite for a while when it was used last time
> though.
Thanks, I'll run some test just to be sure.
> Your patch looks very good and I definitely ack this :)
Thanks!
^ permalink raw reply
* [PATCH] pppoe: drop PPPOX_ZOMBIEs in pppoe_flush_dev
From: Ulrich Weber @ 2011-04-04 12:33 UTC (permalink / raw)
To: davem; +Cc: netdev
otherwise we loop forever if a PPPoE socket was set
to PPPOX_ZOMBIE state by a PADT message when the
ethernet device is going down afterwards.
Signed-off-by: Ulrich Weber <uweber@astaro.com>
---
drivers/net/pppoe.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 78c0e3c..71b1d8f 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -317,7 +317,7 @@ static void pppoe_flush_dev(struct net_device *dev)
lock_sock(sk);
if (po->pppoe_dev == dev &&
- sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+ sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
pppox_unbind_sock(sk);
sk->sk_state = PPPOX_ZOMBIE;
sk->sk_state_change(sk);
--
1.7.1
^ permalink raw reply related
* Re: [PATCH RESEND] net: convert xen-netfront to hw_features
From: Ian Campbell @ 2011-04-04 12:29 UTC (permalink / raw)
To: David Miller
Cc: Jeremy Fitzhardinge, konrad.wilk@oracle.com,
netdev@vger.kernel.org, virtualization@lists.linux-foundation.org,
xen-devel@lists.xensource.com, mirq-linux@rere.qmqm.pl
In-Reply-To: <20110401.205455.70198735.davem@davemloft.net>
On Sat, 2011-04-02 at 04:54 +0100, David Miller wrote:
> From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Date: Thu, 31 Mar 2011 13:01:35 +0200 (CEST)
>
> > Not tested in any way. The original code for offload setting seems broken
> > as it resets the features on every netback reconnect.
> >
> > This will set GSO_ROBUST at device creation time (earlier than connect time).
> >
> > RX checksum offload is forced on - so advertise as it is.
> >
> > Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>
> Applied.
Thanks, but unfortunately the patch results in the features all being
disabled by default, since they are not set in the initial dev->features
and the initial dev->wanted_features is based on features & hw_features.
The ndo_fix_features hook only clears features and doesn't add new
features (nor should it AFAICT).
Features cannot be negotiated with the backend until xennet_connect().
The carrier is not enabled until the end of that function, therefore I
think it is safe to start with a full set of features in dev->features
and rely on the call to netdev_update_features() in xennet_connect() to
clear those which turn out to be unavailable.
The following works for me, I guess the alternative is for
xennet_connect() to expand dev->features based on what it detects? Or is
there a mechanism for a driver to inform the core that a new hardware
feature has become available (I doubt that really happens on physical
h/w so I guess not).
Ian.
8<-----------------
>From 0b56469abe56efae415b4603ef508ce9aec0e4c1 Mon Sep 17 00:00:00 2001
From: Ian Campbell <ian.campbell@citrix.com>
Date: Mon, 4 Apr 2011 10:58:50 +0100
Subject: [PATCH] xen: netfront: assume all hw features are available until backend connection setup
We need to assume that all features will be available when registering the
netdev otherwise they are ommitted from the initial set of
dev->wanted_features. When we connect to the backed we reduce the set as
necessary due to the call to netdev_update_features() in xennet_connect().
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: mirq-linux@rere.qmqm.pl
Cc: netdev@vger.kernel.org <netdev@vger.kernel.org>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: konrad.wilk@oracle.com
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: xen-devel@lists.xensource.com
---
drivers/net/xen-netfront.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 0cfe4cc..db9a763 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1251,6 +1251,14 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev
NETIF_F_GSO_ROBUST;
netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
+ /*
+ * Assume that all hw features are available for now. This set
+ * will be adjusted by the call to netdev_update_features() in
+ * xennet_connect() which is the earliest point where we can
+ * negotiate with the backend regarding supported features.
+ */
+ netdev->features |= netdev->hw_features;
+
SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops);
SET_NETDEV_DEV(netdev, &dev->dev);
--
1.7.2.5
^ permalink raw reply related
* Re: Re: Re: [PATCH] X86:NET:Replaced a deprecated function .
From: wanlong.gao @ 2011-04-04 10:05 UTC (permalink / raw)
To: Dominik Brodowski; +Cc: davem, padovan, joe, marcel, netdev, linux-kernel
In-Reply-To: <201104041743511096883@gmail.com>
I see the issue , but it is sorry that I don't know whether it is capable, yes .
So just ignore my stupid patch .
Thanks for your comments, and benefited a lot.
^ permalink raw reply
* Re: [PATCH 07/19] timberdale: mfd_cell is now implicitly available to drivers
From: Samuel Ortiz @ 2011-04-04 10:03 UTC (permalink / raw)
To: Grant Likely
Cc: Andres Salomon, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown,
khali-PUYAD+kWke1g9hUCZPvPmw, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
Peter Korsgaard, Mauro Carvalho Chehab, David Brownell,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Mocean Laboratories, Greg Kroah-Hartman
In-Reply-To: <BANLkTi=bq=OGzXFp7qiBr7x_BnGOWf=DRQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Fri, Apr 01, 2011 at 05:58:44PM -0600, Grant Likely wrote:
> On Fri, Apr 1, 2011 at 5:52 PM, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote:
> > On Fri, Apr 01, 2011 at 11:56:35AM -0600, Grant Likely wrote:
> >> On Fri, Apr 1, 2011 at 11:47 AM, Andres Salomon <dilinger@queued.net> wrote:
> >> > On Fri, 1 Apr 2011 13:20:31 +0200
> >> > Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote:
> >> >
> >> >> Hi Grant,
> >> >>
> >> >> On Thu, Mar 31, 2011 at 05:05:22PM -0600, Grant Likely wrote:
> >> > [...]
> >> >> > Gah. Not all devices instantiated via mfd will be an mfd device,
> >> >> > which means that the driver may very well expect an *entirely
> >> >> > different* platform_device pointer; which further means a very high
> >> >> > potential of incorrectly dereferenced structures (as evidenced by a
> >> >> > patch series that is not bisectable). For instance, the xilinx ip
> >> >> > cores are used by more than just mfd.
> >> >> I agree. Since the vast majority of the MFD subdevices are MFD
> >> >> specific IPs, I overlooked that part. The impacted drivers are the
> >> >> timberdale and the DaVinci voice codec ones.
> >>
> >> Another option is you could do this for MFD devices:
> >>
> >> struct mfd_device {
> >> struct platform_devce pdev;
> >> struct mfd_cell *cell;
> >> };
> >>
> >> However, that requires that drivers using the mfd_cell will *never*
> >> get instantiated outside of the mfd infrastructure, and there is no
> >> way to protect against this so it is probably a bad idea.
> >>
> >> Or, mfd_cell could be added to platform_device directly which would
> >> *by far* be the safest option at the cost of every platform_device
> >> having a mostly unused mfd_cell pointer. Not a significant cost in my
> >> opinion.
> > I thought about this one, but I had the impression people would want to kill
> > me for adding an MFD specific pointer to platform_device. I guess it's worth
> > giving it a try since it would be a simple and safe solution.
> > I'll look at it later this weekend.
> >
> > Thanks for the input.
>
> [cc'ing gregkh because we're talking about modifying struct platform_device]
>
> I'll back you up on this one. It is a far better solution than the
> alternatives. At least with mfd, it covers a large set of devices. I
> think there is a strong argument for doing this. Or alternatively,
> the particular interesting fields from mfd_cell could be added to
> platform_device. What information do child devices need access to?
In some cases, they need the whole cell to clone it. So I'm up for adding an
mfd_cell pointer to the platform_device structure.
Below is a tentative patch. This is a first step and would fix all
regressions. I tried to keep the MFD dependencies as small as possible, which
is why I placed the pdev->mfd_cell building code in mfd-core.c
The second step would be to get rid of mfd_get_data() and have all subdrivers
going back to the regular platform_data way. They would no longer be dependant
on the MFD code except for those who really need it. In that case they could
just call mfd_get_cell() and get full access to their MFD cell.
---
drivers/mfd/mfd-core.c | 27 ++++++++++++++++++++++-----
include/linux/mfd/core.h | 7 +++++--
include/linux/platform_device.h | 5 +++++
3 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index d01574d..c0fc1c0 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -18,6 +18,21 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>
+static int mfd_platform_add_cell(struct platform_device *pdev, const struct mfd_cell *cell)
+{
+ struct mfd_cell *c;
+
+ if (cell == NULL)
+ return 0;
+
+ c = kmemdup(cell, sizeof(struct mfd_cell), GFP_KERNEL);
+ if (c == NULL)
+ return -ENOMEM;
+
+ pdev->mfd_cell = c;
+ return 0;
+}
+
int mfd_cell_enable(struct platform_device *pdev)
{
const struct mfd_cell *cell = mfd_get_cell(pdev);
@@ -75,7 +90,7 @@ static int mfd_add_device(struct device *parent, int id,
pdev->dev.parent = parent;
- ret = platform_device_add_data(pdev, cell, sizeof(*cell));
+ ret = mfd_platform_add_cell(pdev, cell);
if (ret)
goto fail_res;
@@ -104,17 +119,17 @@ static int mfd_add_device(struct device *parent, int id,
if (!cell->ignore_resource_conflicts) {
ret = acpi_check_resource_conflict(res);
if (ret)
- goto fail_res;
+ goto fail_cell;
}
}
ret = platform_device_add_resources(pdev, res, cell->num_resources);
if (ret)
- goto fail_res;
+ goto fail_cell;
ret = platform_device_add(pdev);
if (ret)
- goto fail_res;
+ goto fail_cell;
if (cell->pm_runtime_no_callbacks)
pm_runtime_no_callbacks(&pdev->dev);
@@ -123,7 +138,8 @@ static int mfd_add_device(struct device *parent, int id,
return 0;
-/* platform_device_del(pdev); */
+fail_cell:
+ kfree(pdev->mfd_cell);
fail_res:
kfree(res);
fail_device:
@@ -171,6 +187,7 @@ static int mfd_remove_devices_fn(struct device *dev, void *c)
if (!*usage_count || (cell->usage_count < *usage_count))
*usage_count = cell->usage_count;
+ kfree(pdev->mfd_cell);
platform_device_unregister(pdev);
return 0;
}
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index ad1b19a..0e4d3a6 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -86,7 +86,7 @@ extern int mfd_clone_cell(const char *cell, const char **clones,
*/
static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
{
- return pdev->dev.platform_data;
+ return pdev->mfd_cell;
}
/*
@@ -95,7 +95,10 @@ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
*/
static inline void *mfd_get_data(struct platform_device *pdev)
{
- return mfd_get_cell(pdev)->mfd_data;
+ if (pdev->mfd_cell != NULL)
+ return mfd_get_cell(pdev)->mfd_data;
+ else
+ return pdev->dev.platform_data;
}
extern int mfd_add_devices(struct device *parent, int id,
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index d96db98..734d254 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -14,6 +14,8 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>
+struct mfd_cell;
+
struct platform_device {
const char * name;
int id;
@@ -23,6 +25,9 @@ struct platform_device {
const struct platform_device_id *id_entry;
+ /* MFD cell pointer */
+ struct mfd_cell *mfd_cell;
+
/* arch specific additions */
struct pdev_archdata archdata;
};
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply related
* [PATCH] xen: drop anti-dependency on X86_VISWS (Was: Re: [PATCH] xen: netfront: fix declaration order)
From: Ian Campbell @ 2011-04-04 9:55 UTC (permalink / raw)
To: David Miller
Cc: eric.dumazet@gmail.com, mirq-linux@rere.qmqm.pl,
netdev@vger.kernel.org, Jeremy Fitzhardinge,
konrad.wilk@oracle.com, xen-devel@lists.xensource.com,
virtualization@lists.linux-foundation.org, Randy Dunlap,
AndreyPanin, linux-visws-devel, Thomas Gleixner, Ingo Molnar,
H. Peter Anvin
In-Reply-To: <20110403.172407.91341067.davem@davemloft.net>
On Mon, 2011-04-04 at 01:24 +0100, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Sun, 03 Apr 2011 13:07:19 +0200
>
> > [PATCH] xen: netfront: fix declaration order
> >
> > Must declare xennet_fix_features() and xennet_set_features() before
> > using them.
> >
> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> > Cc: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>
> Ugh, it makes no sense that XEN won't make it into the x86_32
> allmodconfig build. Those dependencies in arch/x86/xen/Kconfig
> are terrible.
You mean the "!X86_VISWS" I presume? It doesn't make sense to me either.
Or at least I'm not sure why this single X86_32_NON_STANDARD machine is
more special than the others to require an anti-dependency like this.
It seems to have originally appeared from f0f32fccbffa on
CONFIG_PARAVIRT due to a conflict around ARCH_SETUP() and subsequently
got pushed down to CONFIG_XEN. However ARCH_SETUP doesn't exist any more
and I think the subarch stuff has been much improved since then so there
should be no conflict any more.
I dropped the dependency and, with a bit of fiddling, was able to build
a kernel with both CONFIG_X86_VISWS and CONFIG_XEN which booted as a Xen
domU.
tglx, Andrey, to get VISWS to build I had to comment out some code in
arch/x86/platform/visws/visws_quirks.c which seems to have been missed
during some irq_chip update or something?
CC arch/x86/platform/visws/visws_quirks.o
arch/x86/platform/visws/visws_quirks.c: In function 'startup_piix4_master_irq':
arch/x86/platform/visws/visws_quirks.c:474: warning: no return statement in function returning non-void
arch/x86/platform/visws/visws_quirks.c: At top level:
arch/x86/platform/visws/visws_quirks.c:495: error: unknown field 'mask' specified in initializer
arch/x86/platform/visws/visws_quirks.c:495: warning: initialization from incompatible pointer type
arch/x86/platform/visws/visws_quirks.c: In function 'set_piix4_virtual_irq_type':
arch/x86/platform/visws/visws_quirks.c:583: error: 'struct irq_chip' has no member named 'enable'
arch/x86/platform/visws/visws_quirks.c:583: error: 'struct irq_chip' has no member named 'unmask'
arch/x86/platform/visws/visws_quirks.c:584: error: 'struct irq_chip' has no member named 'disable'
arch/x86/platform/visws/visws_quirks.c:584: error: 'struct irq_chip' has no member named 'mask'
arch/x86/platform/visws/visws_quirks.c:585: error: 'struct irq_chip' has no member named 'unmask'
arch/x86/platform/visws/visws_quirks.c:585: error: 'struct irq_chip' has no member named 'unmask'
arch/x86/platform/visws/visws_quirks.c: In function 'visws_pre_intr_init':
arch/x86/platform/visws/visws_quirks.c:602: error: expected expression before '>' token
make[4]: *** [arch/x86/platform/visws/visws_quirks.o] Error 1
Ian
8<--------
From db0ae26f479306ee8ebcfe2a08aa56a6dfe63987 Mon Sep 17 00:00:00 2001
From: Ian Campbell <ian.campbell@citrix.com>
Date: Mon, 4 Apr 2011 10:27:47 +0100
Subject: [PATCH] xen: drop anti-dependency on X86_VISWS
This seems to have been added in f0f32fccbffa to avoid a conflict arising from
the long deceased ARCH_SETUP() macro and subsequently pushed down to the XEN
option.
As far as I can tell the conflict is no longer present and by dropping the
dependency I was able to build a kernel which has both CONFIG_XEN and
CONFIG_X86_VISWS enabled and boot it on Xen. I didn't try it on the VISWS
platform.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: konrad.wilk@oracle.com
Cc: xen-devel@lists.xensource.com
Cc: Randy Dunlap <randy.dunlap@oracle.com>
Cc: Andrey Panin <pazke@donpac.ru>
Cc: linux-visws-devel@lists.sf.net
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
---
arch/x86/xen/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index 1c7121b..65d7b13 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -6,7 +6,7 @@ config XEN
bool "Xen guest support"
select PARAVIRT
select PARAVIRT_CLOCK
- depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
+ depends on X86_64 || (X86_32 && X86_PAE)
depends on X86_CMPXCHG && X86_TSC
help
This is the Linux Xen port. Enabling this will allow the
--
1.7.2.5
^ permalink raw reply related
* Re: Re: [PATCH] X86:NET:Replaced a deprecated function .
From: Dominik Brodowski @ 2011-04-04 9:53 UTC (permalink / raw)
To: wanlong.gao; +Cc: davem, padovan, joe, marcel, netdev, linux-kernel
In-Reply-To: <201104041743511096883@gmail.com>
On Mon, Apr 04, 2011 at 05:44:00PM +0800, wanlong.gao wrote:
> You means that some drivers still not capable of IRQF_SHARED?
That's the issue. I do not know whether this driver is capable of
IRQF_SHARED as it should be. If it is, you may replace the
pcmcia_request_exclusive_irq() with pcmcia_request_irq(), and the warning
will be gone.
Best,
Dominik
^ permalink raw reply
* Re: Re: [PATCH] X86:NET:Replaced a deprecated function .
From: wanlong.gao @ 2011-04-04 9:44 UTC (permalink / raw)
To: Dominik Brodowski; +Cc: davem, padovan, joe, marcel, netdev, linux-kernel
In-Reply-To: <20110404093620.GA4896@isilmar-3.linta.de>
You means that some drivers still not capable of IRQF_SHARED?
Thanks
^ permalink raw reply
* Re: Support e1000 M88 PHY registers in -d
From: Ben Hutchings @ 2011-04-04 9:41 UTC (permalink / raw)
To: Jeff Kirsher; +Cc: Anthony DeRobertis, netdev, e1000-devel, 574574
In-Reply-To: <BANLkTik7G82DwhA_EU8KrKJO25+W=yjWFg@mail.gmail.com>
On Mon, 2011-04-04 at 01:36 -0700, Jeff Kirsher wrote:
> On Sat, Apr 2, 2011 at 09:24, Ben Hutchings <bhutchings@solarflare.com> wrote:
> > Anthony,
> >
> > I'm now upstream maintainer for ethtool so I've picked up your patch
> > again.
> >
> > On Fri, 2010-03-19 at 00:32 -0400, Anthony DeRobertis wrote:
> >> Package: ethtool
> >> Version: 1:2.6.33-1
> >> Severity: wishlist
> >>
> >> The M88 PHY registers contain useful information like the cable length
> >> estimate and the MDI/MDIX status. The attached patch makes -d dump
> >> them.
> >
> > Patches for ethtool should include a commit message and Signed-off-by
> > line, as in the Linux kernel. See sections 2 and 12 of
> > <http://www.kernel.org/doc/Documentation/SubmittingPatches>. They
> > should be sent to this address and to netdev.
> >
> > I'm forwarding this patch to netdev and the e1000 developers for review.
> >
> > Ben.
>
> Thanks Ben. Just to be clear, have you applied these e1000 changes to
> the ethtool?
[...]
I have not applied these changes either anywhere.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH] X86:NET:Replaced a deprecated function .
From: Dominik Brodowski @ 2011-04-04 9:36 UTC (permalink / raw)
To: wanlong.gao; +Cc: davem, padovan, joe, marcel, netdev, linux-kernel
In-Reply-To: <1301909548-20031-1-git-send-email-wanlong.gao@gmail.com>
On Mon, Apr 04, 2011 at 05:32:28PM +0800, wanlong.gao@gmail.com wrote:
> From: Wanlong Gao <wanlong.gao@gmail.com>
>
> kernel_warning: pcmcia_request_exclusive_irq is deprecated .
NACK. This papers over the issue, instead of fixing it. To properly fix it,
one needs to verify that the IRQ handler used in this driver is capable of
handling a shared IRQ line.
Best,
Dominik
> Signed-off-by: Wanlong Gao <wanlong.gao@gmail.com>
> ---
> drivers/net/pcmcia/nmclan_cs.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
> index 76683d9..bf97231
> --- a/drivers/net/pcmcia/nmclan_cs.c
> +++ b/drivers/net/pcmcia/nmclan_cs.c
> @@ -625,7 +625,7 @@ static int nmclan_config(struct pcmcia_device *link)
> ret = pcmcia_request_io(link);
> if (ret)
> goto failed;
> - ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
> + ret = __pcmcia_request_exclusive_irq(link, mace_interrupt);
> if (ret)
> goto failed;
> ret = pcmcia_enable_device(link);
> --
> 1.7.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* [PATCH] X86:NET:Replaced a deprecated function .
From: wanlong.gao @ 2011-04-04 9:32 UTC (permalink / raw)
To: linux, davem, padovan, joe, marcel; +Cc: netdev, linux-kernel, Wanlong Gao
From: Wanlong Gao <wanlong.gao@gmail.com>
kernel_warning: pcmcia_request_exclusive_irq is deprecated .
Signed-off-by: Wanlong Gao <wanlong.gao@gmail.com>
---
drivers/net/pcmcia/nmclan_cs.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 76683d9..bf97231
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -625,7 +625,7 @@ static int nmclan_config(struct pcmcia_device *link)
ret = pcmcia_request_io(link);
if (ret)
goto failed;
- ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
+ ret = __pcmcia_request_exclusive_irq(link, mace_interrupt);
if (ret)
goto failed;
ret = pcmcia_enable_device(link);
--
1.7.3
^ permalink raw reply related
* Re: [PATCH] MAINTAINERS: add entry for Xen network backend
From: Ian Campbell @ 2011-04-04 9:12 UTC (permalink / raw)
To: David Miller
Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
xen-devel@lists.xensource.com, akpm@linux-foundation.org,
torvalds@linux-foundation.org
In-Reply-To: <20110404.020748.212408124.davem@davemloft.net>
On Mon, 2011-04-04 at 10:07 +0100, David Miller wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> Date: Mon, 4 Apr 2011 09:26:07 +0100
>
> > +XEN NETWORK BACKEND DRIVER
> > +M: Ian Campbell <ian.campbell@citrix.com>
> > +L: xen-devel@lists.xensource.com (moderated for non-subscribers)
> > +S: Supported
> > +F: drivers/net/xen-netback/*
> > +
>
> To me there isn't much reason to have patch and other discussions
> about a network driver on a moderated XEN list (which the majority of
> core network developers are not subscribed to).
>
> If anything, list both. But not listing netdev is pretty pointless.
get_maintainer.pl lists both (due to the umbrella netdev entry) so I
didn't think it was required here also, I stand corrected.
8<-------------------------------------
>From 6c71610a1155eecc72f22529513bc130cfab3fe2 Mon Sep 17 00:00:00 2001
From: Ian Campbell <ian.campbell@citrix.com>
Date: Mon, 4 Apr 2011 09:15:29 +0100
Subject: [PATCH] MAINTAINERS: add entry for Xen network backend
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: netdev@vger.kernel.org
Cc: xen-devel@lists.xensource.com
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
---
MAINTAINERS | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 6b4b9cd..649600c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6916,6 +6916,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.
S: Maintained
F: drivers/platform/x86
+XEN NETWORK BACKEND DRIVER
+M: Ian Campbell <ian.campbell@citrix.com>
+L: xen-devel@lists.xensource.com (moderated for non-subscribers)
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/xen-netback/*
+
XEN PCI SUBSYSTEM
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
L: xen-devel@lists.xensource.com (moderated for non-subscribers)
--
1.7.2.5
^ permalink raw reply related
* Re: [PATCH] MAINTAINERS: add entry for Xen network backend
From: David Miller @ 2011-04-04 9:07 UTC (permalink / raw)
To: ian.campbell; +Cc: linux-kernel, netdev, xen-devel, akpm, torvalds
In-Reply-To: <1301905567-7880-1-git-send-email-ian.campbell@citrix.com>
From: Ian Campbell <ian.campbell@citrix.com>
Date: Mon, 4 Apr 2011 09:26:07 +0100
> +XEN NETWORK BACKEND DRIVER
> +M: Ian Campbell <ian.campbell@citrix.com>
> +L: xen-devel@lists.xensource.com (moderated for non-subscribers)
> +S: Supported
> +F: drivers/net/xen-netback/*
> +
To me there isn't much reason to have patch and other discussions
about a network driver on a moderated XEN list (which the majority of
core network developers are not subscribed to).
If anything, list both. But not listing netdev is pretty pointless.
^ permalink raw reply
* Re: Support e1000 M88 PHY registers in -d
From: Jeff Kirsher @ 2011-04-04 8:36 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Anthony DeRobertis, netdev, e1000-devel, 574574
In-Reply-To: <1301761441.10056.197.camel@localhost>
On Sat, Apr 2, 2011 at 09:24, Ben Hutchings <bhutchings@solarflare.com> wrote:
> Anthony,
>
> I'm now upstream maintainer for ethtool so I've picked up your patch
> again.
>
> On Fri, 2010-03-19 at 00:32 -0400, Anthony DeRobertis wrote:
>> Package: ethtool
>> Version: 1:2.6.33-1
>> Severity: wishlist
>>
>> The M88 PHY registers contain useful information like the cable length
>> estimate and the MDI/MDIX status. The attached patch makes -d dump
>> them.
>
> Patches for ethtool should include a commit message and Signed-off-by
> line, as in the Linux kernel. See sections 2 and 12 of
> <http://www.kernel.org/doc/Documentation/SubmittingPatches>. They
> should be sent to this address and to netdev.
>
> I'm forwarding this patch to netdev and the e1000 developers for review.
>
> Ben.
Thanks Ben. Just to be clear, have you applied these e1000 changes to
the ethtool?
>
> [...]
>> diff -rdbU3 ethtool-2.6.33/e1000.c ethtool-2.6.33.new//e1000.c
>> --- ethtool-2.6.33/e1000.c 2009-02-08 18:52:12.000000000 -0500
>> +++ ethtool-2.6.33.new//e1000.c 2010-03-19 00:26:33.044052610 -0400
>> @@ -110,6 +110,61 @@
>> #define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
>> #define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
>>
>> +/* M88E1000 PHY Specific Status Register */
>> +#define M88_PSSR_JABBER 0x0001 /* 1=Jabber */
>> +#define M88_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
>> +#define M88_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */
>> +#define M88_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
>> +#define M88_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M;
>> + * 3=110-140M;4=>140M */
>> +#define M88_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */
>> +#define M88_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
>> +#define M88_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */
>> +#define M88_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
>> +#define M88_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
>> +#define M88_PSSR_10MBS 0x0000 /* 00=10Mbs */
>> +#define M88_PSSR_100MBS 0x4000 /* 01=100Mbs */
>> +#define M88_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
>> +
>> +#define M88_PSSR_CL_0_50 (0<<7)
>> +#define M88_PSSR_CL_50_80 (1<<7)
>> +#define M88_PSSR_CL_80_110 (2<<7)
>> +#define M88_PSSR_CL_110_140 (3<<7)
>> +#define M88_PSSR_CL_140_PLUS (4<<7)
>> +
>> +/* M88E1000 PHY Specific Control Register */
>> +#define M88_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */
>> +#define M88_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
>> +#define M88_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
>> +#define M88_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low,
>> + * 0=CLK125 toggling
>> + */
>> +#define M88_PSCR_MDI_MASK 0x0060
>> +#define M88_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
>> + /* Manual MDI configuration */
>> +#define M88_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
>> +#define M88_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover,
>> + * 100BASE-TX/10BASE-T:
>> + * MDI Mode
>> + */
>> +#define M88_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled
>> + * all speeds.
>> + */
>> +#define M88_PSCR_10BT_EXT_DIST_ENABLE 0x0080
>> + /* 1=Enable Extended 10BASE-T distance
>> + * (Lower 10BASE-T RX Threshold)
>> + * 0=Normal 10BASE-T RX Threshold */
>> +#define M88_PSCR_MII_5BIT_ENABLE 0x0100
>> + /* 1=5-Bit interface in 100BASE-TX
>> + * 0=MII interface in 100BASE-TX */
>> +#define M88_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */
>> +#define M88_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */
>> +#define M88_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
>> +
>> +#define M88_PSCR_POLARITY_REVERSAL_SHIFT 1
>> +#define M88_PSCR_AUTO_X_MODE_SHIFT 5
>> +#define M88_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
>> +
>> /* PCI Device IDs */
>> #define E1000_DEV_ID_82542 0x1000
>> #define E1000_DEV_ID_82543GC_FIBER 0x1001
>> @@ -515,6 +570,72 @@
>> regs_buff[12] == 1 ? "IGP" :
>> regs_buff[12] == 2 ? "IGP2" : "unknown" );
>>
>> + if (0 == regs_buff[12]) {
>> + reg = regs_buff[13];
>> + fprintf(stdout,
>> + "M88 PHY STATUS REGISTER: 0x%08X\n"
>> + " Jabber: %s\n"
>> + " Polarity: %s\n"
>> + " Downshifted: %s\n"
>> + " MDI/MDIX: %s\n"
>> + " Cable Length Estimate: %s meters\n"
>> + " Link State: %s\n"
>> + " Speed & Duplex Resolved: %s\n"
>> + " Page Received: %s\n"
>> + " Duplex: %s\n"
>> + " Speed: %s mbps\n",
>> + reg,
>> + reg & M88_PSSR_JABBER ? "yes" : "no",
>> + reg & M88_PSSR_REV_POLARITY ? "reverse" : "normal",
>> + reg & M88_PSSR_DOWNSHIFT ? "yes" : "no",
>> + reg & M88_PSSR_MDIX ? "MDIX" : "MDI",
>> + ((reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_0_50 ? "0-50"
>> + : (reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_50_80 ? "50-80"
>> + : (reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_80_110 ? "80-110"
>> + : (reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_110_140? "110-140"
>> + : (reg & M88_PSSR_CABLE_LENGTH)==M88_PSSR_CL_140_PLUS ? "140+"
>> + : "unknown"),
>> + reg & M88_PSSR_LINK ? "Up" : "Down",
>> + reg & M88_PSSR_SPD_DPLX_RESOLVED ? "Yes" : "No",
>> + reg & M88_PSSR_PAGE_RCVD ? "Yes" : "No",
>> + reg & M88_PSSR_DPLX ? "Full" : "Half",
>> + ((reg & M88_PSSR_SPEED)==M88_PSSR_10MBS ? "10"
>> + : (reg & M88_PSSR_SPEED)==M88_PSSR_100MBS ? "100"
>> + : (reg & M88_PSSR_SPEED)==M88_PSSR_1000MBS ? "1000"
>> + : "unknown")
>> + );
>> +
>> + reg = regs_buff[17];
>> + fprintf(stdout,
>> + "M88 PHY CONTROL REGISTER: 0x%08X\n"
>> + " Jabber funtion: %s\n"
>> + " Auto-polarity: %s\n"
>> + " SQE Test: %s\n"
>> + " CLK125: %s\n"
>> + " Auto-MDIX: %s\n"
>> + " Extended 10Base-T Distance: %s\n"
>> + " 100Base-TX Interface: %s\n"
>> + " Scrambler: %s\n"
>> + " Force Link Good: %s\n"
>> + " Assert CRS on Transmit: %s\n",
>> + reg,
>> + reg & M88_PSCR_JABBER_DISABLE ? "disabled" : "enabled",
>> + reg & M88_PSCR_POLARITY_REVERSAL ? "enabled" : "disabled",
>> + reg & M88_PSCR_SQE_TEST ? "enabled" : "disabled",
>> + reg & M88_PSCR_CLK125_DISABLE ? "disabled" : "enabled",
>> + ((reg & M88_PSCR_MDI_MASK)==M88_PSCR_MDI_MANUAL_MODE ? "force MDI"
>> + : (reg & M88_PSCR_MDI_MASK)==M88_PSCR_MDIX_MANUAL_MODE ? "force MDIX"
>> + : (reg & M88_PSCR_MDI_MASK)==M88_PSCR_AUTO_X_1000T ? "1000 auto, 10/100 MDI"
>> + : (reg & M88_PSCR_MDI_MASK)==M88_PSCR_AUTO_X_MODE ? "auto"
>> + : "wtf"),
>> + reg & M88_PSCR_10BT_EXT_DIST_ENABLE ? "enabled" : "disabled",
>> + reg & M88_PSCR_MII_5BIT_ENABLE ? "5-bit" : "MII",
>> + reg & M88_PSCR_SCRAMBLER_DISABLE ? "disabled" : "enabled",
>> + reg & M88_PSCR_FORCE_LINK_GOOD ? "forced" : "disabled",
>> + reg & M88_PSCR_ASSERT_CRS_ON_TX ? "enabled" : "disabled"
>> + );
>> + }
>> +
>> return 0;
>> }
>>
> --
> Ben Hutchings, Senior Software Engineer, Solarflare
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Cheers,
Jeff
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox