* [patch net v3 1/4] net/sched: Change tc_action refcnt and bindcnt to atomic
From: Chris Mi @ 2017-10-17 1:20 UTC (permalink / raw)
To: netdev; +Cc: jhs, lucasb, xiyou.wangcong, jiri, davem
In-Reply-To: <1508203218-17998-1-git-send-email-chrism@mellanox.com>
If many filters share the same action. That action's refcnt and bindcnt
could be manipulated by many RCU callbacks at the same time. This patch
makes these operations atomic.
Fixes commit in pre-git era.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Chris Mi <chrism@mellanox.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
include/net/act_api.h | 4 ++--
net/sched/act_api.c | 21 +++++++++++----------
net/sched/act_bpf.c | 4 ++--
net/sched/act_connmark.c | 4 ++--
net/sched/act_csum.c | 4 ++--
net/sched/act_gact.c | 4 ++--
net/sched/act_ife.c | 4 ++--
net/sched/act_ipt.c | 4 ++--
net/sched/act_mirred.c | 4 ++--
net/sched/act_nat.c | 4 ++--
net/sched/act_pedit.c | 4 ++--
net/sched/act_police.c | 4 ++--
net/sched/act_sample.c | 4 ++--
net/sched/act_simple.c | 4 ++--
net/sched/act_skbedit.c | 4 ++--
net/sched/act_skbmod.c | 4 ++--
net/sched/act_tunnel_key.c | 4 ++--
net/sched/act_vlan.c | 4 ++--
18 files changed, 45 insertions(+), 44 deletions(-)
diff --git a/include/net/act_api.h b/include/net/act_api.h
index b944e0eb..a469ab6 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -25,8 +25,8 @@ struct tc_action {
struct tcf_idrinfo *idrinfo;
u32 tcfa_index;
- int tcfa_refcnt;
- int tcfa_bindcnt;
+ atomic_t tcfa_refcnt;
+ atomic_t tcfa_bindcnt;
u32 tcfa_capab;
int tcfa_action;
struct tcf_t tcfa_tm;
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index da6fa82..9c0224d 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -88,12 +88,13 @@ int __tcf_idr_release(struct tc_action *p, bool bind, bool strict)
if (p) {
if (bind)
- p->tcfa_bindcnt--;
- else if (strict && p->tcfa_bindcnt > 0)
+ atomic_dec(&p->tcfa_bindcnt);
+ else if (strict && atomic_read(&p->tcfa_bindcnt) > 0)
return -EPERM;
- p->tcfa_refcnt--;
- if (p->tcfa_bindcnt <= 0 && p->tcfa_refcnt <= 0) {
+ atomic_dec(&p->tcfa_refcnt);
+ if (atomic_read(&p->tcfa_bindcnt) == 0 &&
+ atomic_read(&p->tcfa_refcnt) == 0) {
if (p->ops->cleanup)
p->ops->cleanup(p, bind);
tcf_idr_remove(p->idrinfo, p);
@@ -245,8 +246,8 @@ bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
if (index && p) {
if (bind)
- p->tcfa_bindcnt++;
- p->tcfa_refcnt++;
+ atomic_inc(&p->tcfa_bindcnt);
+ atomic_inc(&p->tcfa_refcnt);
*a = p;
return true;
}
@@ -274,9 +275,9 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
if (unlikely(!p))
return -ENOMEM;
- p->tcfa_refcnt = 1;
+ atomic_set(&p->tcfa_refcnt, 1);
if (bind)
- p->tcfa_bindcnt = 1;
+ atomic_set(&p->tcfa_bindcnt, 1);
if (cpustats) {
p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
@@ -727,7 +728,7 @@ static void cleanup_a(struct list_head *actions, int ovr)
return;
list_for_each_entry(a, actions, list)
- a->tcfa_refcnt--;
+ atomic_dec(&a->tcfa_refcnt);
}
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
@@ -751,7 +752,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
}
act->order = i;
if (ovr)
- act->tcfa_refcnt++;
+ atomic_inc(&act->tcfa_refcnt);
list_add_tail(&act->list, actions);
}
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index c0c707e..4ddf281 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -141,8 +141,8 @@ static int tcf_bpf_dump(struct sk_buff *skb, struct tc_action *act,
struct tcf_bpf *prog = to_bpf(act);
struct tc_act_bpf opt = {
.index = prog->tcf_index,
- .refcnt = prog->tcf_refcnt - ref,
- .bindcnt = prog->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&prog->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&prog->tcf_bindcnt) - bind,
.action = prog->tcf_action,
};
struct tcf_t tm;
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
index 10b7a88..d2cf658 100644
--- a/net/sched/act_connmark.c
+++ b/net/sched/act_connmark.c
@@ -153,8 +153,8 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
struct tc_connmark opt = {
.index = ci->tcf_index,
- .refcnt = ci->tcf_refcnt - ref,
- .bindcnt = ci->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&ci->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
.action = ci->tcf_action,
.zone = ci->zone,
};
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index 1c40caa..b9ca424 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -575,8 +575,8 @@ static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind,
.update_flags = p->update_flags,
.index = p->tcf_index,
.action = p->tcf_action,
- .refcnt = p->tcf_refcnt - ref,
- .bindcnt = p->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&p->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&p->tcf_bindcnt) - bind,
};
struct tcf_t t;
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index e29a48e..b1326b7 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -169,8 +169,8 @@ static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_gact *gact = to_gact(a);
struct tc_gact opt = {
.index = gact->tcf_index,
- .refcnt = gact->tcf_refcnt - ref,
- .bindcnt = gact->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&gact->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&gact->tcf_bindcnt) - bind,
.action = gact->tcf_action,
};
struct tcf_t t;
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index 8ccd358..5cdcc87 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -551,8 +551,8 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
struct tcf_ife_info *ife = to_ife(a);
struct tc_ife opt = {
.index = ife->tcf_index,
- .refcnt = ife->tcf_refcnt - ref,
- .bindcnt = ife->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&ife->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
.action = ife->tcf_action,
.flags = ife->flags,
};
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index d9e399a..02c14dc 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -277,8 +277,8 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind,
if (unlikely(!t))
goto nla_put_failure;
- c.bindcnt = ipt->tcf_bindcnt - bind;
- c.refcnt = ipt->tcf_refcnt - ref;
+ c.bindcnt = atomic_read(&ipt->tcf_bindcnt) - bind;
+ c.refcnt = atomic_read(&ipt->tcf_refcnt) - ref;
strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name);
if (nla_put(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t) ||
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 416627c..aeeeb38 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -249,8 +249,8 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind,
struct tc_mirred opt = {
.index = m->tcf_index,
.action = m->tcf_action,
- .refcnt = m->tcf_refcnt - ref,
- .bindcnt = m->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&m->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&m->tcf_bindcnt) - bind,
.eaction = m->tcfm_eaction,
.ifindex = m->tcfm_ifindex,
};
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index c365d01..58fa1ae 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -256,8 +256,8 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a,
.index = p->tcf_index,
.action = p->tcf_action,
- .refcnt = p->tcf_refcnt - ref,
- .bindcnt = p->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&p->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&p->tcf_bindcnt) - bind,
};
struct tcf_t t;
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 491fe5de..27b9fea 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -391,8 +391,8 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
opt->nkeys = p->tcfp_nkeys;
opt->flags = p->tcfp_flags;
opt->action = p->tcf_action;
- opt->refcnt = p->tcf_refcnt - ref;
- opt->bindcnt = p->tcf_bindcnt - bind;
+ opt->refcnt = atomic_read(&p->tcf_refcnt) - ref;
+ opt->bindcnt = atomic_read(&p->tcf_bindcnt) - bind;
if (p->tcfp_keys_ex) {
tcf_pedit_key_ex_dump(skb, p->tcfp_keys_ex, p->tcfp_nkeys);
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 3bb2ebf..d8a1ac6 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -272,8 +272,8 @@ static int tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a,
.action = police->tcf_action,
.mtu = police->tcfp_mtu,
.burst = PSCHED_NS2TICKS(police->tcfp_burst),
- .refcnt = police->tcf_refcnt - ref,
- .bindcnt = police->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&police->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&police->tcf_bindcnt) - bind,
};
struct tcf_t t;
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
index ec986ae..64889a4 100644
--- a/net/sched/act_sample.c
+++ b/net/sched/act_sample.c
@@ -179,8 +179,8 @@ static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a,
struct tc_sample opt = {
.index = s->tcf_index,
.action = s->tcf_action,
- .refcnt = s->tcf_refcnt - ref,
- .bindcnt = s->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&s->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&s->tcf_bindcnt) - bind,
};
struct tcf_t t;
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index e7b57e5..ec7e397 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -148,8 +148,8 @@ static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_defact *d = to_defact(a);
struct tc_defact opt = {
.index = d->tcf_index,
- .refcnt = d->tcf_refcnt - ref,
- .bindcnt = d->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&d->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&d->tcf_bindcnt) - bind,
.action = d->tcf_action,
};
struct tcf_t t;
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index 59949d6..2b05e56 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -172,8 +172,8 @@ static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_skbedit *d = to_skbedit(a);
struct tc_skbedit opt = {
.index = d->tcf_index,
- .refcnt = d->tcf_refcnt - ref,
- .bindcnt = d->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&d->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&d->tcf_bindcnt) - bind,
.action = d->tcf_action,
};
struct tcf_t t;
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c
index b642ad3..ca1ddf9 100644
--- a/net/sched/act_skbmod.c
+++ b/net/sched/act_skbmod.c
@@ -201,8 +201,8 @@ static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_skbmod_params *p = rtnl_dereference(d->skbmod_p);
struct tc_skbmod opt = {
.index = d->tcf_index,
- .refcnt = d->tcf_refcnt - ref,
- .bindcnt = d->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&d->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&d->tcf_bindcnt) - bind,
.action = d->tcf_action,
};
struct tcf_t t;
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 30c9627..158d472 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -250,8 +250,8 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_tunnel_key_params *params;
struct tc_tunnel_key opt = {
.index = t->tcf_index,
- .refcnt = t->tcf_refcnt - ref,
- .bindcnt = t->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&t->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&t->tcf_bindcnt) - bind,
};
struct tcf_t tm;
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
index 16eb067..e2d7aab 100644
--- a/net/sched/act_vlan.c
+++ b/net/sched/act_vlan.c
@@ -208,8 +208,8 @@ static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_vlan *v = to_vlan(a);
struct tc_vlan opt = {
.index = v->tcf_index,
- .refcnt = v->tcf_refcnt - ref,
- .bindcnt = v->tcf_bindcnt - bind,
+ .refcnt = atomic_read(&v->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&v->tcf_bindcnt) - bind,
.action = v->tcf_action,
.v_action = v->tcfv_action,
};
--
1.8.3.1
^ permalink raw reply related
* [patch net v3 3/4] selftests: Introduce a new script to generate tc batch file
From: Chris Mi @ 2017-10-17 1:20 UTC (permalink / raw)
To: netdev; +Cc: jhs, lucasb, xiyou.wangcong, jiri, davem
In-Reply-To: <1508203218-17998-1-git-send-email-chrism@mellanox.com>
# ./tdc_batch.py -h
usage: tdc_batch.py [-h] [-n NUMBER] [-o] [-s] [-p] device file
TC batch file generator
positional arguments:
device device name
file batch file name
optional arguments:
-h, --help show this help message and exit
-n NUMBER, --number NUMBER
how many lines in batch file
-o, --skip_sw skip_sw (offload), by default skip_hw
-s, --share_action all filters share the same action
-p, --prio all filters have different prio
Signed-off-by: Chris Mi <chrism@mellanox.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Lucas Bates <lucasb@mojatatu.com>
---
tools/testing/selftests/tc-testing/tdc_batch.py | 62 +++++++++++++++++++++++++
1 file changed, 62 insertions(+)
create mode 100755 tools/testing/selftests/tc-testing/tdc_batch.py
diff --git a/tools/testing/selftests/tc-testing/tdc_batch.py b/tools/testing/selftests/tc-testing/tdc_batch.py
new file mode 100755
index 0000000..707c6bf
--- /dev/null
+++ b/tools/testing/selftests/tc-testing/tdc_batch.py
@@ -0,0 +1,62 @@
+#!/usr/bin/python3
+
+"""
+tdc_batch.py - a script to generate TC batch file
+
+Copyright (C) 2017 Chris Mi <chrism@mellanox.com>
+"""
+
+import argparse
+
+parser = argparse.ArgumentParser(description='TC batch file generator')
+parser.add_argument("device", help="device name")
+parser.add_argument("file", help="batch file name")
+parser.add_argument("-n", "--number", type=int,
+ help="how many lines in batch file")
+parser.add_argument("-o", "--skip_sw",
+ help="skip_sw (offload), by default skip_hw",
+ action="store_true")
+parser.add_argument("-s", "--share_action",
+ help="all filters share the same action",
+ action="store_true")
+parser.add_argument("-p", "--prio",
+ help="all filters have different prio",
+ action="store_true")
+args = parser.parse_args()
+
+device = args.device
+file = open(args.file, 'w')
+
+number = 1
+if args.number:
+ number = args.number
+
+skip = "skip_hw"
+if args.skip_sw:
+ skip = "skip_sw"
+
+share_action = ""
+if args.share_action:
+ share_action = "index 1"
+
+prio = "prio 1"
+if args.prio:
+ prio = ""
+ if number > 0x4000:
+ number = 0x4000
+
+index = 0
+for i in range(0x100):
+ for j in range(0x100):
+ for k in range(0x100):
+ mac = ("%02x:%02x:%02x" % (i, j, k))
+ src_mac = "e4:11:00:" + mac
+ dst_mac = "e4:12:00:" + mac
+ cmd = ("filter add dev %s %s protocol ip parent ffff: flower %s "
+ "src_mac %s dst_mac %s action drop %s" %
+ (device, prio, skip, src_mac, dst_mac, share_action))
+ file.write("%s\n" % cmd)
+ index += 1
+ if index >= number:
+ file.close()
+ exit(0)
--
1.8.3.1
^ permalink raw reply related
* [patch net v3 2/4] net/sched: Use action array instead of action list as parameter
From: Chris Mi @ 2017-10-17 1:20 UTC (permalink / raw)
To: netdev; +Cc: jhs, lucasb, xiyou.wangcong, jiri, davem
In-Reply-To: <1508203218-17998-1-git-send-email-chrism@mellanox.com>
When destroying filters, actions should be destroyed first.
The pointers of each action are saved in an array. TC doesn't
use the array directly, but put all actions in a doubly linked
list and use that list as parameter.
There is no problem if each filter has its own actions. But if
some filters share the same action, when these filters are
destroyed, RCU callback fl_destroy_filter() may be called at the
same time. That means the same action's 'struct list_head list'
could be manipulated at the same time. It may point to an invalid
address so that system will panic.
This patch uses the action array directly to fix this issue.
Fixes commit in pre-git era.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Chris Mi <chrism@mellanox.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
include/net/act_api.h | 7 ++--
net/sched/act_api.c | 103 +++++++++++++++++++++++++++++++-------------------
net/sched/cls_api.c | 18 +++------
3 files changed, 75 insertions(+), 53 deletions(-)
diff --git a/include/net/act_api.h b/include/net/act_api.h
index a469ab6..081a313 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -148,16 +148,17 @@ static inline int tcf_idr_release(struct tc_action *a, bool bind)
int tcf_register_action(struct tc_action_ops *a, struct pernet_operations *ops);
int tcf_unregister_action(struct tc_action_ops *a,
struct pernet_operations *ops);
-int tcf_action_destroy(struct list_head *actions, int bind);
+int tcf_action_destroy(struct tc_action **actions, int nr, int bind);
int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
int nr_actions, struct tcf_result *res);
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
struct nlattr *est, char *name, int ovr, int bind,
- struct list_head *actions);
+ struct tc_action **actions, int *nr);
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
struct nlattr *nla, struct nlattr *est,
char *name, int ovr, int bind);
-int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
+int tcf_action_dump(struct sk_buff *skb, struct tc_action **actions, int nr,
+ int bind, int ref);
int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int);
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 9c0224d..391d560 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -513,13 +513,15 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
}
EXPORT_SYMBOL(tcf_action_exec);
-int tcf_action_destroy(struct list_head *actions, int bind)
+int tcf_action_destroy(struct tc_action **actions, int nr, int bind)
{
const struct tc_action_ops *ops;
- struct tc_action *a, *tmp;
+ struct tc_action *a;
int ret = 0;
+ int i;
- list_for_each_entry_safe(a, tmp, actions, list) {
+ for (i = 0; i < nr; i++) {
+ a = actions[i];
ops = a->ops;
ret = __tcf_idr_release(a, bind, true);
if (ret == ACT_P_DELETED)
@@ -568,14 +570,16 @@ int tcf_action_destroy(struct list_head *actions, int bind)
}
EXPORT_SYMBOL(tcf_action_dump_1);
-int tcf_action_dump(struct sk_buff *skb, struct list_head *actions,
+int tcf_action_dump(struct sk_buff *skb, struct tc_action **actions, int nr,
int bind, int ref)
{
struct tc_action *a;
- int err = -EINVAL;
struct nlattr *nest;
+ int err = -EINVAL;
+ int i;
- list_for_each_entry(a, actions, list) {
+ for (i = 0; i < nr; i++) {
+ a = actions[i];
nest = nla_nest_start(skb, a->order);
if (nest == NULL)
goto nla_put_failure;
@@ -700,10 +704,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
if (TC_ACT_EXT_CMP(a->tcfa_action, TC_ACT_GOTO_CHAIN)) {
err = tcf_action_goto_chain_init(a, tp);
if (err) {
- LIST_HEAD(actions);
-
- list_add_tail(&a->list, &actions);
- tcf_action_destroy(&actions, bind);
+ tcf_action_destroy(&a, 1, bind);
return ERR_PTR(err);
}
}
@@ -720,23 +721,27 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
return ERR_PTR(err);
}
-static void cleanup_a(struct list_head *actions, int ovr)
+static void cleanup_a(struct tc_action **actions, int nr, int ovr)
{
struct tc_action *a;
+ int i;
if (!ovr)
return;
- list_for_each_entry(a, actions, list)
+ for (i = 0; i < nr; i++) {
+ a = actions[i];
atomic_dec(&a->tcfa_refcnt);
+ }
}
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
struct nlattr *est, char *name, int ovr, int bind,
- struct list_head *actions)
+ struct tc_action **actions, int *nr)
{
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
struct tc_action *act;
+ int n = 0;
int err;
int i;
@@ -753,17 +758,19 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
act->order = i;
if (ovr)
atomic_inc(&act->tcfa_refcnt);
- list_add_tail(&act->list, actions);
+ actions[n++] = act;
}
+ *nr = n;
/* Remove the temp refcnt which was necessary to protect against
* destroying an existing action which was being replaced
*/
- cleanup_a(actions, ovr);
+ cleanup_a(actions, n, ovr);
return 0;
err:
- tcf_action_destroy(actions, bind);
+ tcf_action_destroy(actions, n, bind);
+ *nr = 0;
return err;
}
@@ -811,9 +818,9 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *p,
return -1;
}
-static int tca_get_fill(struct sk_buff *skb, struct list_head *actions,
- u32 portid, u32 seq, u16 flags, int event, int bind,
- int ref)
+static int tca_get_fill(struct sk_buff *skb, struct tc_action **actions,
+ int nr, u32 portid, u32 seq, u16 flags, int event,
+ int bind, int ref)
{
struct tcamsg *t;
struct nlmsghdr *nlh;
@@ -832,7 +839,7 @@ static int tca_get_fill(struct sk_buff *skb, struct list_head *actions,
if (nest == NULL)
goto out_nlmsg_trim;
- if (tcf_action_dump(skb, actions, bind, ref) < 0)
+ if (tcf_action_dump(skb, actions, nr, bind, ref) < 0)
goto out_nlmsg_trim;
nla_nest_end(skb, nest);
@@ -847,14 +854,14 @@ static int tca_get_fill(struct sk_buff *skb, struct list_head *actions,
static int
tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
- struct list_head *actions, int event)
+ struct tc_action **actions, int nr, int event)
{
struct sk_buff *skb;
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
if (!skb)
return -ENOBUFS;
- if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
+ if (tca_get_fill(skb, actions, nr, portid, n->nlmsg_seq, 0, event,
0, 0) <= 0) {
kfree_skb(skb);
return -EINVAL;
@@ -968,7 +975,8 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
}
static int
-tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
+tcf_del_notify(struct net *net, struct nlmsghdr *n,
+ struct tc_action **actions, int nr,
u32 portid)
{
int ret;
@@ -978,14 +986,14 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
if (!skb)
return -ENOBUFS;
- if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
- 0, 1) <= 0) {
+ if (tca_get_fill(skb, actions, nr, portid, n->nlmsg_seq, 0,
+ RTM_DELACTION, 0, 1) <= 0) {
kfree_skb(skb);
return -EINVAL;
}
/* now do the delete */
- ret = tcf_action_destroy(actions, 0);
+ ret = tcf_action_destroy(actions, nr, 0);
if (ret < 0) {
kfree_skb(skb);
return ret;
@@ -1002,10 +1010,11 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
u32 portid, int event)
{
- int i, ret;
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
+ struct tc_action **actions;
struct tc_action *act;
- LIST_HEAD(actions);
+ int i, ret;
+ int nr = 0;
ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, NULL);
if (ret < 0)
@@ -1018,6 +1027,11 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
return -EINVAL;
}
+ actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *),
+ GFP_KERNEL);
+ if (!actions)
+ return -ENOMEM;
+
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
act = tcf_action_get_1(net, tb[i], n, portid);
if (IS_ERR(act)) {
@@ -1025,25 +1039,28 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
goto err;
}
act->order = i;
- list_add_tail(&act->list, &actions);
+ actions[nr++] = act;
}
if (event == RTM_GETACTION)
- ret = tcf_get_notify(net, portid, n, &actions, event);
+ ret = tcf_get_notify(net, portid, n, actions, nr, event);
else { /* delete */
- ret = tcf_del_notify(net, n, &actions, portid);
+ ret = tcf_del_notify(net, n, actions, nr, portid);
if (ret)
goto err;
+ kfree(actions);
return ret;
}
err:
if (event != RTM_GETACTION)
- tcf_action_destroy(&actions, 0);
+ tcf_action_destroy(actions, nr, 0);
+ kfree(actions);
return ret;
}
static int
-tcf_add_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
+tcf_add_notify(struct net *net, struct nlmsghdr *n,
+ struct tc_action **actions, int nr,
u32 portid)
{
struct sk_buff *skb;
@@ -1053,7 +1070,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
if (!skb)
return -ENOBUFS;
- if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags,
+ if (tca_get_fill(skb, actions, nr, portid, n->nlmsg_seq, n->nlmsg_flags,
RTM_NEWACTION, 0, 0) <= 0) {
kfree_skb(skb);
return -EINVAL;
@@ -1069,14 +1086,24 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
static int tcf_action_add(struct net *net, struct nlattr *nla,
struct nlmsghdr *n, u32 portid, int ovr)
{
+ struct tc_action **actions;
int ret = 0;
- LIST_HEAD(actions);
+ int nr;
- ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, &actions);
+ actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *),
+ GFP_KERNEL);
+ if (!actions)
+ return -ENOMEM;
+
+ ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0,
+ actions, &nr);
if (ret)
- return ret;
+ goto out;
- return tcf_add_notify(net, n, &actions, portid);
+ ret = tcf_add_notify(net, n, actions, nr, portid);
+out:
+ kfree(actions);
+ return ret;
}
static u32 tcaa_root_flags_allowed = TCA_FLAG_LARGE_DUMP_ON;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 0b2219a..acaa0c6 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -879,8 +879,7 @@ void tcf_exts_destroy(struct tcf_exts *exts)
#ifdef CONFIG_NET_CLS_ACT
LIST_HEAD(actions);
- tcf_exts_to_list(exts, &actions);
- tcf_action_destroy(&actions, TCA_ACT_UNBIND);
+ tcf_action_destroy(exts->actions, exts->nr_actions, TCA_ACT_UNBIND);
kfree(exts->actions);
exts->nr_actions = 0;
#endif
@@ -905,17 +904,14 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
exts->actions[0] = act;
exts->nr_actions = 1;
} else if (exts->action && tb[exts->action]) {
- LIST_HEAD(actions);
- int err, i = 0;
+ int err;
err = tcf_action_init(net, tp, tb[exts->action],
rate_tlv, NULL, ovr, TCA_ACT_BIND,
- &actions);
+ exts->actions,
+ &exts->nr_actions);
if (err)
return err;
- list_for_each_entry(act, &actions, list)
- exts->actions[i++] = act;
- exts->nr_actions = i;
}
}
#else
@@ -961,14 +957,12 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts)
* tc data even if iproute2 was newer - jhs
*/
if (exts->type != TCA_OLD_COMPAT) {
- LIST_HEAD(actions);
-
nest = nla_nest_start(skb, exts->action);
if (nest == NULL)
goto nla_put_failure;
- tcf_exts_to_list(exts, &actions);
- if (tcf_action_dump(skb, &actions, 0, 0) < 0)
+ if (tcf_action_dump(skb, exts->actions,
+ exts->nr_actions, 0, 0) < 0)
goto nla_put_failure;
nla_nest_end(skb, nest);
} else if (exts->police) {
--
1.8.3.1
^ permalink raw reply related
* [patch net v3 4/4] selftests: Introduce a new test case to tc testsuite
From: Chris Mi @ 2017-10-17 1:20 UTC (permalink / raw)
To: netdev; +Cc: jhs, lucasb, xiyou.wangcong, jiri, davem
In-Reply-To: <1508203218-17998-1-git-send-email-chrism@mellanox.com>
In this patchset, we fixed a tc bug. This patch adds the test case
that reproduces the bug. To run this test case, user should specify
an existing NIC device:
# sudo ./tdc.py -d enp4s0f0
This test case belongs to category "flower". If user doesn't specify
a NIC device, the test cases belong to "flower" will not be run.
In this test case, we create 1M filters and all filters share the same
action. When destroying all filters, kernel should not panic. It takes
about 18s to run it.
Signed-off-by: Chris Mi <chrism@mellanox.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Lucas Bates <lucasb@mojatatu.com>
---
.../tc-testing/tc-tests/filters/tests.json | 23 +++++++++++++++++++++-
tools/testing/selftests/tc-testing/tdc.py | 20 +++++++++++++++----
tools/testing/selftests/tc-testing/tdc_config.py | 2 ++
3 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json
index c727b96..5fa02d8 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json
@@ -17,5 +17,26 @@
"teardown": [
"$TC qdisc del dev $DEV1 ingress"
]
+ },
+ {
+ "id": "d052",
+ "name": "Add 1M filters with the same action",
+ "category": [
+ "filter",
+ "flower"
+ ],
+ "setup": [
+ "$TC qdisc add dev $DEV2 ingress",
+ "./tdc_batch.py $DEV2 $BATCH_FILE --share_action -n 1000000"
+ ],
+ "cmdUnderTest": "$TC -b $BATCH_FILE",
+ "expExitCode": "0",
+ "verifyCmd": "$TC actions list action gact",
+ "matchPattern": "action order 0: gact action drop.*index 1 ref 1000000 bind 1000000",
+ "matchCount": "1",
+ "teardown": [
+ "$TC qdisc del dev $DEV2 ingress",
+ "/bin/rm $BATCH_FILE"
+ ]
}
-]
\ No newline at end of file
+]
diff --git a/tools/testing/selftests/tc-testing/tdc.py b/tools/testing/selftests/tc-testing/tdc.py
index cd61b78..5f11f5d 100755
--- a/tools/testing/selftests/tc-testing/tdc.py
+++ b/tools/testing/selftests/tc-testing/tdc.py
@@ -88,7 +88,7 @@ def prepare_env(cmdlist):
exit(1)
-def test_runner(filtered_tests):
+def test_runner(filtered_tests, args):
"""
Driver function for the unit tests.
@@ -105,6 +105,8 @@ def test_runner(filtered_tests):
for tidx in testlist:
result = True
tresult = ""
+ if "flower" in tidx["category"] and args.device == None:
+ continue
print("Test " + tidx["id"] + ": " + tidx["name"])
prepare_env(tidx["setup"])
(p, procout) = exec_cmd(tidx["cmdUnderTest"])
@@ -152,6 +154,10 @@ def ns_create():
exec_cmd(cmd, False)
cmd = 'ip -s $NS link set $DEV1 up'
exec_cmd(cmd, False)
+ cmd = 'ip link set $DEV2 netns $NS'
+ exec_cmd(cmd, False)
+ cmd = 'ip -s $NS link set $DEV2 up'
+ exec_cmd(cmd, False)
def ns_destroy():
@@ -211,7 +217,8 @@ def set_args(parser):
help='Execute the single test case with specified ID')
parser.add_argument('-i', '--id', action='store_true', dest='gen_id',
help='Generate ID numbers for new test cases')
- return parser
+ parser.add_argument('-d', '--device',
+ help='Execute the test case in flower category')
return parser
@@ -225,6 +232,8 @@ def check_default_settings(args):
if args.path != None:
NAMES['TC'] = args.path
+ if args.device != None:
+ NAMES['DEV2'] = args.device
if not os.path.isfile(NAMES['TC']):
print("The specified tc path " + NAMES['TC'] + " does not exist.")
exit(1)
@@ -381,14 +390,17 @@ def set_operation_mode(args):
if (len(alltests) == 0):
print("Cannot find a test case with ID matching " + target_id)
exit(1)
- catresults = test_runner(alltests)
+ catresults = test_runner(alltests, args)
print("All test results: " + "\n\n" + catresults)
elif (len(target_category) > 0):
+ if (target_category == "flower") and args.device == None:
+ print("Please specify a NIC device (-d) to run category flower")
+ exit(1)
if (target_category not in ucat):
print("Specified category is not present in this file.")
exit(1)
else:
- catresults = test_runner(testcases[target_category])
+ catresults = test_runner(testcases[target_category], args)
print("Category " + target_category + "\n\n" + catresults)
ns_destroy()
diff --git a/tools/testing/selftests/tc-testing/tdc_config.py b/tools/testing/selftests/tc-testing/tdc_config.py
index 0108737..b635251 100644
--- a/tools/testing/selftests/tc-testing/tdc_config.py
+++ b/tools/testing/selftests/tc-testing/tdc_config.py
@@ -12,6 +12,8 @@ NAMES = {
# Name of veth devices to be created for the namespace
'DEV0': 'v0p0',
'DEV1': 'v0p1',
+ 'DEV2': '',
+ 'BATCH_FILE': './batch.txt',
# Name of the namespace to use
'NS': 'tcut'
}
--
1.8.3.1
^ permalink raw reply related
* Re: net-next: WARNING: CPU: 0 PID: 1544 at net/ipv4/tcp_input.c:889
From: Eric Dumazet @ 2017-10-17 1:32 UTC (permalink / raw)
To: Andrei Vagin, Yuchung Cheng; +Cc: Linux Kernel Network Developers
In-Reply-To: <CANaxB-z=3y+_Eihq-NGRr7YtnyBBNtRo2r4WgKVgTzcJMwTzvw@mail.gmail.com>
On Mon, Oct 16, 2017 at 4:11 PM, Andrei Vagin <avagin@gmail.com> wrote:
> Hi Eric,
>
> Could you take a look at this warning? It may be related with your
> recent patches. First time we saw this warning 7 days ago
> (net-next/master) and now we see it regularly.
>
> I printed tp->fackets_out and state->reord before the warnings and
> here are values for them:
> tp->fackets_out = -1 state->reord = 4
>
> In my case, this warning is triggered for connections which have been
> restored by CRIU.
>
> Let me know if you need any other information. I can reproduce this
> bugs for an hour.
>
> Thanks,
> Andrei
Hi Andrei
We are aware of these recurring issues and Yuchung and other Googlers
decided it was time to remove FACK.
Stay tuned.
^ permalink raw reply
* Re: RFC(v2): Audit Kernel Container IDs
From: Steve Grubb @ 2017-10-17 1:42 UTC (permalink / raw)
To: linux-audit-H+wXaHxf7aLQT0dZR+AlfA
Cc: mszeredi-H+wXaHxf7aLQT0dZR+AlfA, trondmy-7I+n7zu2hftEKMMhf/gKZA,
Andy Lutomirski, jlayton-H+wXaHxf7aLQT0dZR+AlfA, Linux API,
Linux Containers, Linux FS Devel, Linux Kernel, David Howells,
Carlos O'Donell, cgroups-u79uwXL29TY76Z2rM5mHXA,
Eric W. Biederman, Simo Sorce, Linux Network Development,
Casey Schaufler, Eric Paris, Al Viro
In-Reply-To: <20171017003340.whjdkqmkw4lydwy7-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>
On Monday, October 16, 2017 8:33:40 PM EDT Richard Guy Briggs wrote:
> On 2017-10-12 16:33, Casey Schaufler wrote:
> > On 10/12/2017 7:14 AM, Richard Guy Briggs wrote:
> > > Containers are a userspace concept. The kernel knows nothing of them.
> > >
> > > The Linux audit system needs a way to be able to track the container
> > > provenance of events and actions. Audit needs the kernel's help to do
> > > this.
> > >
> > > Since the concept of a container is entirely a userspace concept, a
> > > registration from the userspace container orchestration system initiates
> > > this. This will define a point in time and a set of resources
> > > associated with a particular container with an audit container ID.
> > >
> > > The registration is a pseudo filesystem (proc, since PID tree already
> > > exists) write of a u8[16] UUID representing the container ID to a file
> > > representing a process that will become the first process in a new
> > > container. This write might place restrictions on mount namespaces
> > > required to define a container, or at least careful checking of
> > > namespaces in the kernel to verify permissions of the orchestrator so it
> > > can't change its own container ID. A bind mount of nsfs may be
> > > necessary in the container orchestrator's mntNS.
> > > Note: Use a 128-bit scalar rather than a string to make compares faster
> > > and simpler.
> > >
> > > Require a new CAP_CONTAINER_ADMIN to be able to carry out the
> > > registration.
> >
> > Hang on. If containers are a user space concept, how can
> > you want CAP_CONTAINER_ANYTHING? If there's not such thing as
> > a container, how can you be asking for a capability to manage
> > them?
>
> There is such a thing, but the kernel doesn't know about it yet. This
> same situation exists for loginuid and sessionid which are userspace
> concepts that the kernel tracks for the convenience of userspace. As
> for its name, I'm not particularly picky, so if you don't like
> CAP_CONTAINER_* then I'm fine with CAP_AUDIT_CONTAINERID. It really
> needs to be distinct from CAP_AUDIT_WRITE and CAP_AUDIT_CONTROL since we
> don't want to give the ability to set a containerID to any process that
> is able to do audit logging (such as vsftpd) and similarly we don't want
> to give the orchestrator the ability to control the setup of the audit
> daemon.
A long time ago, we were debating what should guard against rouge processes
from setting the loginuid. Casey argued that the ability to set the loginuid
means they have the ability to control the audit trail. That means that it
should be guarded by CAP_AUDIT_CONTROL. I think the same logic applies today.
The ability to arbitrarily set a container ID means the process has the
ability to indirectly control the audit trail.
-Steve
^ permalink raw reply
* Hello
From: Mrs. AmiraaWilliams @ 2017-10-17 1:50 UTC (permalink / raw)
Hello Dear,
Please forgive me for stressing you with my predicaments as I know
that this letter may come to you as big surprise. Actually, I came
across your E-mail from my personal search afterward I decided to
email you directly believing that you will be honest to fulfill my
final wish before i die. Meanwhile, I am Mrs. Amiraa Williams, 62
years old, from America, and I am suffering from a long time cancer
and from all indication my condition is really deteriorating as my
doctors have confirmed and courageously Advised me that I may not live
beyond two months from now for the reason that my tumor has reached a
critical stage which has defiled all forms of medical treatment, As a
matter of fact, registered nurse by profession while my husband was
dealing on Gold Dust and Gold Dory Bars in Burkina Faso till his
sudden death the year 2008 then I took over his business till date. In
fact, at this moment I have a deposit sum of four million five hundred
thousand US dollars [$4,500,000.00] with one of the leading bank in
Burkina Faso but unfortunately I cannot visit the bank since I’m
critically sick and powerless to do anything myself but my bank
account officer advised me to assign any of my trustworthy relative,
friends or partner with authorization letter to stand as the recipient
of my money but sorrowfully I don’t have any reliable relative and no
child.
Therefore, I want you to receive the money and take 50% to take care
of yourself and family while 50% should be use basically on
humanitarian purposes mostly to orphanages home, Motherless babies
home, less privileged and disable citizens and widows around the
world. as soon as I receive your respond I shall send you the full
details with my pictures, banking records and with full contacts of my
banking institution to communicate them on the matter.
Hope to hear from you soon.
Yours Faithfully,
Mrs. Amiraa Williams
^ permalink raw reply
* Re: [PATCH v3] net: ftgmac100: Request clock and set speed
From: Andrew Jeffery @ 2017-10-17 2:00 UTC (permalink / raw)
To: Joel Stanley, David S . Miller, Benjamin Herrenschmidt
Cc: netdev, linux-kernel
In-Reply-To: <20171013041638.30763-1-joel@jms.id.au>
[-- Attachment #1: Type: text/plain, Size: 3623 bytes --]
On Fri, 2017-10-13 at 12:16 +0800, Joel Stanley wrote:
> According to the ASPEED datasheet, gigabit speeds require a clock of
> 100MHz or higher. Other speeds require 25MHz or higher. This patch
> configures a 100MHz clock if the system has a direct-attached
> PHY, or 25MHz if the system is running NC-SI which is limited to 100MHz.
>
> There appear to be no other upstream users of the FTGMAC100 driver it is
> hard to know the clocking requirements of other platforms. Therefore a
> conservative approach was taken with enabling clocks. If the platform is
> not ASPEED, both requesting the clock and configuring the speed is
> skipped.
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
Tested on an AST2500 EVB and an OpenPOWER Palmetto (AST2400) machine.
Confirmed clock rates were nominally what was requested, and successfully
downloaded a 100MB test file.
Tested-by: Andrew Jeffery <andrew@aj.id.au>
> ---
> Andrew, can you please give this one a spin on hardware?
>
> v3:
> - Fix errors from v2
> v2:
> - only touch the clocks on Aspeed platforms
> - unconditionally call clk_unprepare_disable
>
> drivers/net/ethernet/faraday/ftgmac100.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
> index 9ed8e4b81530..78db8e62a83f 100644
> --- a/drivers/net/ethernet/faraday/ftgmac100.c
> +++ b/drivers/net/ethernet/faraday/ftgmac100.c
> @@ -21,6 +21,7 @@
>
> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>
> +#include <linux/clk.h>
> #include <linux/dma-mapping.h>
> #include <linux/etherdevice.h>
> #include <linux/ethtool.h>
> @@ -59,6 +60,9 @@
> /* Min number of tx ring entries before stopping queue */
> #define TX_THRESHOLD (MAX_SKB_FRAGS + 1)
>
> +#define FTGMAC_100MHZ 100000000
> +#define FTGMAC_25MHZ 25000000
> +
> struct ftgmac100 {
> /* Registers */
> struct resource *res;
> @@ -96,6 +100,7 @@ struct ftgmac100 {
> struct napi_struct napi;
> struct work_struct reset_task;
> struct mii_bus *mii_bus;
> + struct clk *clk;
>
> /* Link management */
> int cur_speed;
> @@ -1734,6 +1739,22 @@ static void ftgmac100_ncsi_handler(struct ncsi_dev *nd)
> nd->link_up ? "up" : "down");
> }
>
> +static void ftgmac100_setup_clk(struct ftgmac100 *priv)
> +{
> + priv->clk = devm_clk_get(priv->dev, NULL);
> + if (IS_ERR(priv->clk))
> + return;
> +
> + clk_prepare_enable(priv->clk);
> +
> + /* Aspeed specifies a 100MHz clock is required for up to
> + * 1000Mbit link speeds. As NCSI is limited to 100Mbit, 25MHz
> + * is sufficient
> + */
> + clk_set_rate(priv->clk, priv->use_ncsi ? FTGMAC_25MHZ :
> + FTGMAC_100MHZ);
> +}
> +
> static int ftgmac100_probe(struct platform_device *pdev)
> {
> struct resource *res;
> @@ -1830,6 +1851,9 @@ static int ftgmac100_probe(struct platform_device *pdev)
> goto err_setup_mdio;
> }
>
> + if (priv->is_aspeed)
> + ftgmac100_setup_clk(priv);
> +
> /* Default ring sizes */
> priv->rx_q_entries = priv->new_rx_q_entries = DEF_RX_QUEUE_ENTRIES;
> priv->tx_q_entries = priv->new_tx_q_entries = DEF_TX_QUEUE_ENTRIES;
> @@ -1883,6 +1907,8 @@ static int ftgmac100_remove(struct platform_device *pdev)
>
> unregister_netdev(netdev);
>
> + clk_disable_unprepare(priv->clk);
> +
> /* There's a small chance the reset task will have been re-queued,
> * during stop, make sure it's gone before we free the structure.
> */
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [iproute2] regression in ss output
From: Eric Dumazet @ 2017-10-17 2:00 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Humberto Alves, Phil Sutter, netdev@vger.kernel.org
In-Reply-To: <20171016142807.47825131@xeon-e3>
On Mon, 2017-10-16 at 14:28 -0700, Stephen Hemminger wrote:
> On Mon, 16 Oct 2017 20:44:07 +0000
> Humberto Alves <hjalves@live.com> wrote:
>
> > Yes, just get rid of this 'if statement'.
> > in6addr_any should be represented as '::', not '*'. Otherwise it's
> > impossible to distinguish IPv4 listening addresses from IPv6. Thank you :)
>
> But IPv6 accepts IPv4 as well.
Not always (IPV6_V6ONLY socket option)
I agree that this recent change in ss is problematic.
Please give us back a way to distinguish IPV6 and IPv4
^ permalink raw reply
* [PATCH net-next] tcp: fix tcp_xmit_retransmit_queue() after rbtree introduction
From: Eric Dumazet @ 2017-10-17 2:38 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Yuchung Cheng
From: Eric Dumazet <edumazet@google.com>
I tried to hard avoiding a call to rb_first() (via tcp_rtx_queue_head)
in tcp_xmit_retransmit_queue(). But this was probably too bold.
Quoting Yuchung :
We might miss re-arming the RTO if tp->retransmit_skb_hint is not NULL.
This can happen when RACK marks the first packet lost again and resets
tp->retransmit_skb_hint for example (tcp_rack_mark_skb_lost())
Fixes: 75c119afe14f ("tcp: implement rb-tree based retransmit queue")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Yuchung Cheng <ycheng@google.com>
---
net/ipv4/tcp_output.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 6c74f2a3977876e691e7355045d4a84a98af1e30..53dc1267c85e668d9a6d5d60d24e6101f7a9c56b 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2921,7 +2921,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
void tcp_xmit_retransmit_queue(struct sock *sk)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
- struct sk_buff *skb, *rtx_head = NULL, *hole = NULL;
+ struct sk_buff *skb, *rtx_head, *hole = NULL;
struct tcp_sock *tp = tcp_sk(sk);
u32 max_segs;
int mib_idx;
@@ -2929,11 +2929,8 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
if (!tp->packets_out)
return;
- skb = tp->retransmit_skb_hint;
- if (!skb) {
- rtx_head = tcp_rtx_queue_head(sk);
- skb = rtx_head;
- }
+ rtx_head = tcp_rtx_queue_head(sk);
+ skb = tp->retransmit_skb_hint ?: rtx_head;
max_segs = tcp_tso_segs(sk, tcp_current_mss(sk));
skb_rbtree_walk_from(skb) {
__u8 sacked;
^ permalink raw reply related
* [net-next PATCH] macvlan/macvtap: Add support for L2 forwarding offloads with macvtap
From: Alexander Duyck @ 2017-10-17 2:44 UTC (permalink / raw)
To: netdev, davem
This patch reverts earlier commit b13ba1b83f52 ("macvlan: forbid L2
fowarding offload for macvtap"). The reason for reverting this is because
the original patch no longer fixes what it previously did as the
underlying structure has changed for macvtap. Specifically macvtap
originally pulled packets directly off of the lowerdev. However in commit
6acf54f1cf0a ("macvtap: Add support of packet capture on macvtap device.")
that code was changed and instead macvtap would listen directly on the
macvtap device itself instead of the lower device. As such, the L2
forwarding offload should now be able to provide a performance advantage of
skipping the checks on the lower dev while not introducing any sort of
regression.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
drivers/net/macvlan.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 858bd66..cfeb0ee 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -596,8 +596,6 @@ static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
.cache_update = eth_header_cache_update,
};
-static struct rtnl_link_ops macvlan_link_ops;
-
static int macvlan_open(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
@@ -613,8 +611,7 @@ static int macvlan_open(struct net_device *dev)
goto hash_add;
}
- if (lowerdev->features & NETIF_F_HW_L2FW_DOFFLOAD &&
- dev->rtnl_link_ops == &macvlan_link_ops) {
+ if (lowerdev->features & NETIF_F_HW_L2FW_DOFFLOAD) {
vlan->fwd_priv =
lowerdev->netdev_ops->ndo_dfwd_add_station(lowerdev, dev);
^ permalink raw reply related
* Re: [PATCH net-next] virtio_net: implement VIRTIO_CONFIG_S_NEEDS_RESET
From: Jason Wang @ 2017-10-17 3:05 UTC (permalink / raw)
To: Willem de Bruijn, Michael S. Tsirkin
Cc: Network Development, David Miller, virtualization,
Willem de Bruijn
In-Reply-To: <CAF=yD-KkUH6=S6Q=Tjtd2Wo=-ebDUt1or-DqjoRV4dTaD8G0WA@mail.gmail.com>
On 2017年10月17日 06:34, Willem de Bruijn wrote:
> On Mon, Oct 16, 2017 at 12:38 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> On Mon, Oct 16, 2017 at 12:04:57PM -0400, Willem de Bruijn wrote:
>>> On Mon, Oct 16, 2017 at 11:31 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
>>>> On Mon, Oct 16, 2017 at 11:03:18AM -0400, Willem de Bruijn wrote:
>>>>>>> +static int virtnet_reset(struct virtnet_info *vi)
>>>>>>> +{
>>>>>>> + struct virtio_device *dev = vi->vdev;
>>>>>>> + int ret;
>>>>>>> +
>>>>>>> + virtio_config_disable(dev);
>>>>>>> + dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
>>>>>>> + virtnet_freeze_down(dev, true);
>>>>>>> + remove_vq_common(vi);
>>>>>>> +
>>>>>>> + virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
>>>>>>> + virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER);
>>>>>>> +
>>>>>>> + ret = virtio_finalize_features(dev);
>>>>>>> + if (ret)
>>>>>>> + goto err;
>>>>>>> +
>>>>>>> + ret = virtnet_restore_up(dev);
>>>>>>> + if (ret)
>>>>>>> + goto err;
>>>>>>> +
>>>>>>> + ret = virtnet_set_queues(vi, vi->curr_queue_pairs);
>>>>>>> + if (ret)
>>>>>>> + goto err;
>>>>>>> +
>>>>>>> + virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
>>>>>>> + virtio_config_enable(dev);
>>>>>>> + return 0;
>>>>>>> +
>>>>>>> +err:
>>>>>>> + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
>>>>>>> + return ret;
>>>>>>> +}
>>>>>>> +
>>>>>>> static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads)
>>>>>>> {
>>>>>>> struct scatterlist sg;
>>>>>> I have a question here though. How do things like MAC address
>>>>>> get restored?
>>>>>>
>>>>>> What about the rx mode?
>>>>>>
>>>>>> vlans?
>>>>> The function as is releases and reinitializes only ring state.
>>>>> Device configuration such as mac and vlan persist across
>>>>> the reset.
>>>> What gave you this impression? Take a look at e.g. this
>>>> code in qemu:
>>>>
>>>> static void virtio_net_reset(VirtIODevice *vdev)
>>>> {
>>>> VirtIONet *n = VIRTIO_NET(vdev);
>>>>
>>>> /* Reset back to compatibility mode */
>>>> n->promisc = 1;
>>>> n->allmulti = 0;
>>>> n->alluni = 0;
>>>> n->nomulti = 0;
>>>> n->nouni = 0;
>>>> n->nobcast = 0;
>>>> /* multiqueue is disabled by default */
>>>> n->curr_queues = 1;
>>>> timer_del(n->announce_timer);
>>>> n->announce_counter = 0;
>>>> n->status &= ~VIRTIO_NET_S_ANNOUNCE;
>>>>
>>>> /* Flush any MAC and VLAN filter table state */
>>>> n->mac_table.in_use = 0;
>>>> n->mac_table.first_multi = 0;
>>>> n->mac_table.multi_overflow = 0;
>>>> n->mac_table.uni_overflow = 0;
>>>> memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
>>>> memcpy(&n->mac[0], &n->nic->conf->macaddr, sizeof(n->mac));
>>>> qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
>>>> memset(n->vlans, 0, MAX_VLAN >> 3);
>>>> }
>>>>
>>>> So device seems to lose all state, you have to re-program it.
>>> Oh, indeed! The guest does not reset its state, so it might
>>> be out of sync with the host after the operation. Was this not
>>> an issue when previously resetting in the context of xdp?
>> I suspect it was broken back then, too.
> Okay. I guess that in principle this is all programmable through
> virtnet_set_rx_mode, virtnet_vlan_rx_add_vid, etc. But it's a
> lot more complex than just restoring virtnet_reset. Will need to
> be careful about concurrency issues at the least. Similar to the
> ones you point out below.
>
The problem has been pointed out during developing virtio-net XDP. But
it may not be a big issue since vhost_net ignores all kinds of the
filters now.
Thanks
^ permalink raw reply
* Re: [PATCH net-next] virtio_net: implement VIRTIO_CONFIG_S_NEEDS_RESET
From: Michael S. Tsirkin @ 2017-10-17 3:44 UTC (permalink / raw)
To: Jason Wang
Cc: Willem de Bruijn, Network Development, David Miller,
virtualization, Willem de Bruijn
In-Reply-To: <ecf3dde0-d4e6-23d5-22a7-05ce45bdafc9@redhat.com>
On Tue, Oct 17, 2017 at 11:05:07AM +0800, Jason Wang wrote:
>
>
> On 2017年10月17日 06:34, Willem de Bruijn wrote:
> > On Mon, Oct 16, 2017 at 12:38 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
> > > On Mon, Oct 16, 2017 at 12:04:57PM -0400, Willem de Bruijn wrote:
> > > > On Mon, Oct 16, 2017 at 11:31 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> > > > > On Mon, Oct 16, 2017 at 11:03:18AM -0400, Willem de Bruijn wrote:
> > > > > > > > +static int virtnet_reset(struct virtnet_info *vi)
> > > > > > > > +{
> > > > > > > > + struct virtio_device *dev = vi->vdev;
> > > > > > > > + int ret;
> > > > > > > > +
> > > > > > > > + virtio_config_disable(dev);
> > > > > > > > + dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
> > > > > > > > + virtnet_freeze_down(dev, true);
> > > > > > > > + remove_vq_common(vi);
> > > > > > > > +
> > > > > > > > + virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
> > > > > > > > + virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER);
> > > > > > > > +
> > > > > > > > + ret = virtio_finalize_features(dev);
> > > > > > > > + if (ret)
> > > > > > > > + goto err;
> > > > > > > > +
> > > > > > > > + ret = virtnet_restore_up(dev);
> > > > > > > > + if (ret)
> > > > > > > > + goto err;
> > > > > > > > +
> > > > > > > > + ret = virtnet_set_queues(vi, vi->curr_queue_pairs);
> > > > > > > > + if (ret)
> > > > > > > > + goto err;
> > > > > > > > +
> > > > > > > > + virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> > > > > > > > + virtio_config_enable(dev);
> > > > > > > > + return 0;
> > > > > > > > +
> > > > > > > > +err:
> > > > > > > > + virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
> > > > > > > > + return ret;
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads)
> > > > > > > > {
> > > > > > > > struct scatterlist sg;
> > > > > > > I have a question here though. How do things like MAC address
> > > > > > > get restored?
> > > > > > >
> > > > > > > What about the rx mode?
> > > > > > >
> > > > > > > vlans?
> > > > > > The function as is releases and reinitializes only ring state.
> > > > > > Device configuration such as mac and vlan persist across
> > > > > > the reset.
> > > > > What gave you this impression? Take a look at e.g. this
> > > > > code in qemu:
> > > > >
> > > > > static void virtio_net_reset(VirtIODevice *vdev)
> > > > > {
> > > > > VirtIONet *n = VIRTIO_NET(vdev);
> > > > >
> > > > > /* Reset back to compatibility mode */
> > > > > n->promisc = 1;
> > > > > n->allmulti = 0;
> > > > > n->alluni = 0;
> > > > > n->nomulti = 0;
> > > > > n->nouni = 0;
> > > > > n->nobcast = 0;
> > > > > /* multiqueue is disabled by default */
> > > > > n->curr_queues = 1;
> > > > > timer_del(n->announce_timer);
> > > > > n->announce_counter = 0;
> > > > > n->status &= ~VIRTIO_NET_S_ANNOUNCE;
> > > > >
> > > > > /* Flush any MAC and VLAN filter table state */
> > > > > n->mac_table.in_use = 0;
> > > > > n->mac_table.first_multi = 0;
> > > > > n->mac_table.multi_overflow = 0;
> > > > > n->mac_table.uni_overflow = 0;
> > > > > memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
> > > > > memcpy(&n->mac[0], &n->nic->conf->macaddr, sizeof(n->mac));
> > > > > qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
> > > > > memset(n->vlans, 0, MAX_VLAN >> 3);
> > > > > }
> > > > >
> > > > > So device seems to lose all state, you have to re-program it.
> > > > Oh, indeed! The guest does not reset its state, so it might
> > > > be out of sync with the host after the operation. Was this not
> > > > an issue when previously resetting in the context of xdp?
> > > I suspect it was broken back then, too.
> > Okay. I guess that in principle this is all programmable through
> > virtnet_set_rx_mode, virtnet_vlan_rx_add_vid, etc. But it's a
> > lot more complex than just restoring virtnet_reset. Will need to
> > be careful about concurrency issues at the least. Similar to the
> > ones you point out below.
> >
>
> The problem has been pointed out during developing virtio-net XDP. But it
> may not be a big issue since vhost_net ignores all kinds of the filters now.
>
> Thanks
It might not keep doing that in the future though.
And virtio-net in userspace doesn't ignore the filters.
--
MST
^ permalink raw reply
* Re: [PATCH net-next] tcp: Check daddr_cache before use in tracepoint
From: Eric Dumazet @ 2017-10-17 3:45 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, xiyou.wangcong
In-Reply-To: <1508189387-27931-1-git-send-email-dsahern@gmail.com>
On Mon, 2017-10-16 at 14:29 -0700, David Ahern wrote:
> Running perf in one window to capture tcp_retransmit_skb tracepoint:
> $ perf record -e tcp:tcp_retransmit_skb -a
>
> And causing a retransmission on an active TCP session (e.g., dropping
> packets in the receiver, changing MTU on the interface to 500 and back
> to 1500) triggers a panic:
...
> Check that daddr_cache is non-NULL before de-referencing.
>
> Fixes: e086101b150a ("tcp: add a tracepoint for tcp retransmission")
> Signed-off-by: David Ahern <dsahern@gmail.com>
> ---
> include/trace/events/tcp.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/trace/events/tcp.h b/include/trace/events/tcp.h
> index 3d1cbd072b7e..13e8ee8af2c8 100644
> --- a/include/trace/events/tcp.h
> +++ b/include/trace/events/tcp.h
> @@ -48,7 +48,8 @@ TRACE_EVENT(tcp_retransmit_skb,
> pin6 = (struct in6_addr *)__entry->saddr_v6;
> *pin6 = np->saddr;
> pin6 = (struct in6_addr *)__entry->daddr_v6;
> - *pin6 = *(np->daddr_cache);
> + if (np->daddr_cache)
> + *pin6 = *(np->daddr_cache);
> } else {
> pin6 = (struct in6_addr *)__entry->saddr_v6;
> ipv6_addr_set_v4mapped(inet->inet_saddr, pin6);
This is weird.
IPV6 TCP uses sk->sk_v6_daddr and sk->->sk_v6_rcv_saddr
So I would rather remove the need to fetch np = inet6_sk(sk) in the
first place, and look at sk->sk_family instead.
No need to get to np at all.
^ permalink raw reply
* Re: [PATCH] bpf: devmap: Check attr->max_entries more carefully
From: John Fastabend @ 2017-10-17 4:30 UTC (permalink / raw)
To: Richard Weinberger, netdev; +Cc: linux-kernel, daniel, ast, sp3485
In-Reply-To: <100542240.i6NpMmsy5C@blindfold>
On 10/15/2017 03:13 PM, Richard Weinberger wrote:
> Am Montag, 16. Oktober 2017, 00:00:20 CEST schrieb Richard Weinberger:
>> max_entries is user controlled and used as input for __alloc_percpu().
>> This function expects that the allocation size is a power of two and
>> less than PCPU_MIN_UNIT_SIZE.
>> Otherwise a WARN() is triggered.
>
> On a second though, I think we should also have a hard limit for ->max_entries
> or check for an overflow here:
>
Or just,
static u64 dev_map_bitmap_size(const union bpf_attr *attr)
{
return BITS_TO_LONGS((u64) attr->max_entries) *
sizeof(unsigned long);
}
Let me know if you want me to send a patch or if you want to.
Thanks,
John
> static u64 dev_map_bitmap_size(const union bpf_attr *attr)
> {
> return BITS_TO_LONGS(attr->max_entries) * sizeof(unsigned long);
> }
>
> Thanks,
> //richard
>
^ permalink raw reply
* [PATCH net] sock_diag: request _diag module only when the family or proto has been registered
From: Xin Long @ 2017-10-17 5:13 UTC (permalink / raw)
To: network dev; +Cc: davem, Marcelo Ricardo Leitner, Sabrina Dubroca
Now when using 'ss' in iproute, kernel would try to load all _diag
modules. It causes the corresponding family or proto modules to be
loaded as well.
Like after 'ss -a', sctp, dccp, af_packet(if it works as a moudle)
will be loaded.
As these family or proto modules are loaded unexpectly, this might
have some security implications.
This patch is to introduce sock_diag_request_module() in which we
only request the _diag module when it's corresponding family or
proto has been registered.
Note that we can't just load _diag module without the family or
proto loaded, as some symbols in _diag module are from the family
or proto moudle.
Reported-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/linux/net.h | 1 +
include/linux/sock_diag.h | 1 +
net/core/sock_diag.c | 32 ++++++++++++++++++++++++--------
net/ipv4/inet_diag.c | 3 +--
net/socket.c | 5 +++++
5 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/include/linux/net.h b/include/linux/net.h
index d97d80d..6c7cf09 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -225,6 +225,7 @@ enum {
int sock_wake_async(struct socket_wq *sk_wq, int how, int band);
int sock_register(const struct net_proto_family *fam);
void sock_unregister(int family);
+bool sock_is_registered(int family);
int __sock_create(struct net *net, int family, int type, int proto,
struct socket **res, int kern);
int sock_create(int family, int type, int proto, struct socket **res);
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index a2f8109..e9a1b8d 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -77,4 +77,5 @@ bool sock_diag_has_destroy_listeners(const struct sock *sk)
void sock_diag_broadcast_destroy(struct sock *sk);
int sock_diag_destroy(struct sock *sk, int err);
+int sock_diag_request_module(int family, int protocol);
#endif
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index 217f4e3..caad6b6 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -7,6 +7,7 @@
#include <net/net_namespace.h>
#include <linux/module.h>
#include <net/sock.h>
+#include <net/protocol.h>
#include <linux/kernel.h>
#include <linux/tcp.h>
#include <linux/workqueue.h>
@@ -207,6 +208,25 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld)
}
EXPORT_SYMBOL_GPL(sock_diag_unregister);
+int sock_diag_request_module(int family, int protocol)
+{
+ if (!protocol) {
+ if (!sock_is_registered(family))
+ return -ENOENT;
+
+ return request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
+ NETLINK_SOCK_DIAG, family);
+ }
+
+ if (family == AF_INET &&
+ !rcu_access_pointer(inet_protos[protocol]))
+ return -ENOENT;
+
+ return request_module("net-pf-%d-proto-%d-type-%d-%d", PF_NETLINK,
+ NETLINK_SOCK_DIAG, family, protocol);
+}
+EXPORT_SYMBOL_GPL(sock_diag_request_module);
+
static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
{
int err;
@@ -220,8 +240,7 @@ static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EINVAL;
if (sock_diag_handlers[req->sdiag_family] == NULL)
- request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
- NETLINK_SOCK_DIAG, req->sdiag_family);
+ sock_diag_request_module(req->sdiag_family, 0);
mutex_lock(&sock_diag_table_mutex);
hndl = sock_diag_handlers[req->sdiag_family];
@@ -247,8 +266,7 @@ static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
case TCPDIAG_GETSOCK:
case DCCPDIAG_GETSOCK:
if (inet_rcv_compat == NULL)
- request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
- NETLINK_SOCK_DIAG, AF_INET);
+ sock_diag_request_module(AF_INET, 0);
mutex_lock(&sock_diag_table_mutex);
if (inet_rcv_compat != NULL)
@@ -281,14 +299,12 @@ static int sock_diag_bind(struct net *net, int group)
case SKNLGRP_INET_TCP_DESTROY:
case SKNLGRP_INET_UDP_DESTROY:
if (!sock_diag_handlers[AF_INET])
- request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
- NETLINK_SOCK_DIAG, AF_INET);
+ sock_diag_request_module(AF_INET, 0);
break;
case SKNLGRP_INET6_TCP_DESTROY:
case SKNLGRP_INET6_UDP_DESTROY:
if (!sock_diag_handlers[AF_INET6])
- request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
- NETLINK_SOCK_DIAG, AF_INET);
+ sock_diag_request_module(AF_INET, 0);
break;
}
return 0;
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index c9c35b6..d10c8fa 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -53,8 +53,7 @@ static DEFINE_MUTEX(inet_diag_table_mutex);
static const struct inet_diag_handler *inet_diag_lock_handler(int proto)
{
if (!inet_diag_table[proto])
- request_module("net-pf-%d-proto-%d-type-%d-%d", PF_NETLINK,
- NETLINK_SOCK_DIAG, AF_INET, proto);
+ sock_diag_request_module(AF_INET, proto);
mutex_lock(&inet_diag_table_mutex);
if (!inet_diag_table[proto])
diff --git a/net/socket.c b/net/socket.c
index c729625..733d657 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2590,6 +2590,11 @@ void sock_unregister(int family)
}
EXPORT_SYMBOL(sock_unregister);
+bool sock_is_registered(int family)
+{
+ return family < NPROTO && rcu_access_pointer(net_families[family]);
+}
+
static int __init sock_init(void)
{
int err;
--
2.1.0
^ permalink raw reply related
* Re: pull-request: mac80211 2017-10-16
From: Johannes Berg @ 2017-10-17 5:46 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: David Miller, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAHmME9rHMMAgJs3uQYpt15V8eh-PjDqioqURA3KPKEhc2a9OEg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, 2017-10-17 at 01:30 +0200, Jason A. Donenfeld wrote:
> Mobile phone right now, so not able to write patch, but you probably
> should be using crypto_memneq for comparing those two keys, not
> memcmp.
I know that's a gut instinct, but I really don't see the point.
If you actually get this to evaluate to "equal", you're already being
attacked, and the attacker already knows they're trying to get the same
key to be installed again. If it's not equal, you execute so much code
beneath, going to the driver etc., that I'd think this particular time
is in the noise.
Also, this isn't something that the attacker can directly observe
anyway, and if they can, then surely the fact that we *skip* a large
amount of code when returning 0 is also observable.
Besides, the only thing that can observe the timing is hostapd or
wpa_supplicant, which obviously know the key (and in the fixed versions
will already have done the comparison themselves).
And lastly, if you wanted to use this as an oracle to get the key back
from the kernel, then you already have admin permissions (in your
network namespace), and can just sniff netlink traffic anyway.
johannes
^ permalink raw reply
* Re: [PATCH] can: check for null sk before deferencing it via the call to sock_net
From: Marc Kleine-Budde @ 2017-10-17 5:49 UTC (permalink / raw)
To: Colin King, Oliver Hartkopp, David S . Miller, linux-can, netdev
Cc: kernel-janitors, linux-kernel
In-Reply-To: <20170908150235.2931-1-colin.king@canonical.com>
[-- Attachment #1.1: Type: text/plain, Size: 950 bytes --]
On 09/08/2017 05:02 PM, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> The assignment of net via call sock_net will dereference sk. This
> is performed before a sanity null check on sk, so there could be
> a potential null dereference on the sock_net call if sk is null.
> Fix this by assigning net after the sk null check. Also replace
> the sk == NULL with the more usual !sk idiom.
>
> Detected by CoverityScan CID#1431862 ("Dereference before null check")
>
> Fixes: 384317ef4187 ("can: network namespace support for CAN_BCM protocol")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Applied to can.
Tnx,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: Linux 4.12+ memory leak on router with i40e NICs
From: Vitezslav Samel @ 2017-10-17 5:51 UTC (permalink / raw)
To: Paweł Staszewski
Cc: Pavlos Parissis, Alexander Duyck, Anders K. Pedersen | Cohaesio,
netdev@vger.kernel.org, intel-wired-lan@lists.osuosl.org,
alexander.h.duyck@intel.com
In-Reply-To: <39696136-2a4a-9c6c-3a63-4485ed2a1bf3@itcare.pl>
On Tue, Oct 17, 2017 at 01:34:29AM +0200, Paweł Staszewski wrote:
> W dniu 2017-10-16 o 18:26, Paweł Staszewski pisze:
> > W dniu 2017-10-16 o 13:20, Pavlos Parissis pisze:
> > > On 15/10/2017 02:58 πμ, Alexander Duyck wrote:
> > > > Hi Pawel,
> > > >
> > > > To clarify is that Dave Miller's tree or Linus's that you are talking
> > > > about? If it is Dave's tree how long ago was it you pulled it since I
> > > > think the fix was just pushed by Jeff Kirsher a few days ago.
> > > >
> > > > The issue should be fixed in the following commit:
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/drivers/net/ethernet/intel/i40e/i40e_txrx.c?id=2b9478ffc550f17c6cd8c69057234e91150f5972
> > >
> > > Do you know when it is going to be available on net-next and
> > > linux-stable repos?
> > >
> > > Cheers,
> > > Pavlos
> > >
> > >
> > I will make some tests today night with "net" git tree where this patch
> > is included.
> > Starting from 0:00 CET
> > :)
> >
> >
> Upgraded and looks like problem is not solved with that patch
> Currently running system with
> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/
> kernel
>
> Still about 0.5GB of memory is leaking somewhere
>
> Also can confirm that the latest kernel where memory is not leaking (with
> use i40e driver intel 710 cards) is 4.11.12
> With kernel 4.11.12 - after hour no change in memory usage.
>
> also checked that with ixgbe instead of i40e with same net.git kernel there
> is no memleak - after hour same memory usage - so for 100% this is i40e
> driver problem.
I have (probably) the same problem here but with X520 cards: booting
4.12.x gives me oops after circa 20 minutes of our workload. Booting
4.9.y is OK. This machine is in production so any testing is very
limited.
Machine was stable for >2 months (on the desk before got to
production) with 4.12.8 but with no traffic on X520 cards.
Cheers,
Vita
^ permalink raw reply
* Re: [net-next 4/9] i40e: Enable 'channel' mode in mqprio for TC configs
From: Yunsheng Lin @ 2017-10-17 6:24 UTC (permalink / raw)
To: Nambiar, Amritha, Jeff Kirsher, davem; +Cc: netdev, nhorman, sassmann, jogreene
In-Reply-To: <4e06d67d-5eea-02ea-1ce2-993666e19b2e@intel.com>
Hi, Nambiar
On 2017/10/17 0:03, Nambiar, Amritha wrote:
> On 10/16/2017 1:53 AM, Yunsheng Lin wrote:
>> Hi, Jeff
>>
>> On 2017/10/14 5:52, Jeff Kirsher wrote:
>>> From: Amritha Nambiar <amritha.nambiar@intel.com>
>>>
>>> The i40e driver is modified to enable the new mqprio hardware
>>> offload mode and factor the TCs and queue configuration by
>>> creating channel VSIs. In this mode, the priority to traffic
>>> class mapping and the user specified queue ranges are used
>>> to configure the traffic classes by setting the mode option to
>>> 'channel'.
>>>
>>> Example:
>>> map 0 0 0 0 1 2 2 3 queues 2@0 2@2 1@4 1@5\
>>> hw 1 mode channel
>>>
>>> qdisc mqprio 8038: root tc 4 map 0 0 0 0 1 2 2 3 0 0 0 0 0 0 0 0
>>> queues:(0:1) (2:3) (4:4) (5:5)
>>> mode:channel
>>> shaper:dcb
>>>
>>> The HW channels created are removed and all the queue configuration
>>> is set to default when the qdisc is detached from the root of the
>>> device.
>>>
>>> This patch also disables setting up channels via ethtool (ethtool -L)
>>> when the TCs are configured using mqprio scheduler.
>>>
>>> The patch also limits setting ethtool Rx flow hash indirection
>>> (ethtool -X eth0 equal N) to max queues configured via mqprio.
>>> The Rx flow hash indirection input through ethtool should be
>>> validated so that it is within in the queue range configured via
>>> tc/mqprio. The bound checking is achieved by reporting the current
>>> rss size to the kernel when queues are configured via mqprio.
>>>
>>> Example:
>>> map 0 0 0 1 0 2 3 0 queues 2@0 4@2 8@6 11@14\
>>> hw 1 mode channel
>>>
>>> Cannot set RX flow hash configuration: Invalid argument
>>>
>>> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
>>> Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
>>> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>>> ---
>>> drivers/net/ethernet/intel/i40e/i40e.h | 3 +
>>> drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 8 +-
>>> drivers/net/ethernet/intel/i40e/i40e_main.c | 457 +++++++++++++++++++------
>>> 3 files changed, 362 insertions(+), 106 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
>>> index bde982541772..024c88474951 100644
>>> --- a/drivers/net/ethernet/intel/i40e/i40e.h
>>> +++ b/drivers/net/ethernet/intel/i40e/i40e.h
>>> @@ -54,6 +54,7 @@
>>> #include <linux/clocksource.h>
>>> #include <linux/net_tstamp.h>
>>> #include <linux/ptp_clock_kernel.h>
>>> +#include <net/pkt_cls.h>
>>> #include "i40e_type.h"
>>> #include "i40e_prototype.h"
>>> #include "i40e_client.h"
>>> @@ -700,6 +701,7 @@ struct i40e_vsi {
>>> enum i40e_vsi_type type; /* VSI type, e.g., LAN, FCoE, etc */
>>> s16 vf_id; /* Virtual function ID for SRIOV VSIs */
>>>
>>> + struct tc_mqprio_qopt_offload mqprio_qopt; /* queue parameters */
>>> struct i40e_tc_configuration tc_config;
>>> struct i40e_aqc_vsi_properties_data info;
>>>
>>> @@ -725,6 +727,7 @@ struct i40e_vsi {
>>> u16 cnt_q_avail; /* num of queues available for channel usage */
>>> u16 orig_rss_size;
>>> u16 current_rss_size;
>>> + bool reconfig_rss;
>>>
>>> u16 next_base_queue; /* next queue to be used for channel setup */
>>>
>>> diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
>>> index afd3ca8d9851..72d5f2cdf419 100644
>>> --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
>>> +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
>>> @@ -2652,7 +2652,7 @@ static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
>>>
>>> switch (cmd->cmd) {
>>> case ETHTOOL_GRXRINGS:
>>> - cmd->data = vsi->num_queue_pairs;
>>> + cmd->data = vsi->rss_size;
>>> ret = 0;
>>> break;
>>> case ETHTOOL_GRXFH:
>>> @@ -3897,6 +3897,12 @@ static int i40e_set_channels(struct net_device *dev,
>>> if (vsi->type != I40E_VSI_MAIN)
>>> return -EINVAL;
>>>
>>> + /* We do not support setting channels via ethtool when TCs are
>>> + * configured through mqprio
>>> + */
>>> + if (pf->flags & I40E_FLAG_TC_MQPRIO)
>>> + return -EINVAL;
>>> +
>>> /* verify they are not requesting separate vectors */
>>> if (!count || ch->rx_count || ch->tx_count)
>>> return -EINVAL;
>>> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
>>> index e23105bee6d1..e803aa1552c6 100644
>>> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
>>> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
>>> @@ -1588,6 +1588,170 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
>>> return 0;
>>> }
>>>
>>> +/**
>>> + * i40e_config_rss_aq - Prepare for RSS using AQ commands
>>> + * @vsi: vsi structure
>>> + * @seed: RSS hash seed
>>> + **/
>>
>> [...]
>>
>>> + * i40e_vsi_set_default_tc_config - set default values for tc configuration
>>> + * @vsi: the VSI being configured
>>> + **/
>>> +static void i40e_vsi_set_default_tc_config(struct i40e_vsi *vsi)
>>> +{
>>> + u16 qcount;
>>> + int i;
>>> +
>>> + /* Only TC0 is enabled */
>>> + vsi->tc_config.numtc = 1;
>>> + vsi->tc_config.enabled_tc = 1;
>>> + qcount = min_t(int, vsi->alloc_queue_pairs,
>>> + i40e_pf_get_max_q_per_tc(vsi->back));
>>> + for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
>>> + /* For the TC that is not enabled set the offset to to default
>>> + * queue and allocate one queue for the given TC.
>>> + */
>>> + vsi->tc_config.tc_info[i].qoffset = 0;
>>> + if (i == 0)
>>> + vsi->tc_config.tc_info[i].qcount = qcount;
>>> + else
>>> + vsi->tc_config.tc_info[i].qcount = 1;
>>> + vsi->tc_config.tc_info[i].netdev_tc = 0;
>>> + }
>>> +}
>>> +
>>> /**
>>> * i40e_setup_tc - configure multiple traffic classes
>>> * @netdev: net device to configure
>>> - * @tc: number of traffic classes to enable
>>> + * @type_data: tc offload data
>>> **/
>>> -static int i40e_setup_tc(struct net_device *netdev, u8 tc)
>>> +static int i40e_setup_tc(struct net_device *netdev, void *type_data)
>>> {
>>> + struct tc_mqprio_qopt_offload *mqprio_qopt = type_data;
>>> struct i40e_netdev_priv *np = netdev_priv(netdev);
>>> struct i40e_vsi *vsi = np->vsi;
>>> struct i40e_pf *pf = vsi->back;
>>> - u8 enabled_tc = 0;
>>> + u8 enabled_tc = 0, num_tc, hw;
>>> + bool need_reset = false;
>>> int ret = -EINVAL;
>>> + u16 mode;
>>> int i;
>>>
>>> - /* Check if DCB enabled to continue */
>>> - if (!(pf->flags & I40E_FLAG_DCB_ENABLED)) {
>>> - netdev_info(netdev, "DCB is not enabled for adapter\n");
>>> - goto exit;
>>> + num_tc = mqprio_qopt->qopt.num_tc;
>>> + hw = mqprio_qopt->qopt.hw;
>>> + mode = mqprio_qopt->mode;
>>> + if (!hw) {
>>
>> When stack call the ndo_setup_tc, then qopt.hw is always non-zero, Can you
>> tell me why you need to check for this?
>
> This needs to be checked here because when the qdisc is detached from
> root of the device, i.e. 'tc qdisc del dev <interface>', the 'mqprio
> destroy' flow calls ndo_setup_tc with the offload values zeroed out for
> proper clean up.
I see, Thanks.
>
> -Amritha
>
>>
>> Thanks,
>> Yunsheng Lin
>>
>>> + pf->flags &= ~I40E_FLAG_TC_MQPRIO;
>>> + memcpy(&vsi->mqprio_qopt, mqprio_qopt, sizeof(*mqprio_qopt));
>>> + goto config_tc;
>>> }
>>>
>>> /* Check if MFP enabled */
>>> if (pf->flags & I40E_FLAG_MFP_ENABLED) {
>>> - netdev_info(netdev, "Configuring TC not supported in MFP mode\n");
>>> - goto exit;
>>> + netdev_info(netdev,
>>> + "Configuring TC not supported in MFP mode\n");
>>> + return ret;
>>> }
>>> + switch (mode) {
>>> + case TC_MQPRIO_MODE_DCB:
>>> + pf->flags &= ~I40E_FLAG_TC_MQPRIO;
>>>
>>> - /* Check whether tc count is within enabled limit */
>>> - if (tc > i40e_pf_get_num_tc(pf)) {
>>> - netdev_info(netdev, "TC count greater than enabled on link for adapter\n");
>>> - goto exit;
>>> + /* Check if DCB enabled to continue */
>>> + if (!(pf->flags & I40E_FLAG_DCB_ENABLED)) {
>>> + netdev_info(netdev,
>>> + "DCB is not enabled for adapter\n");
>>> + return ret;
>>> + }
>>> +
>>> + /* Check whether tc count is within enabled limit */
>>> + if (num_tc > i40e_pf_get_num_tc(pf)) {
>>> + netdev_info(netdev,
>>> + "TC count greater than enabled on link for adapter\n");
>>> + return ret;
>>> + }
>>> + break;
>>> + case TC_MQPRIO_MODE_CHANNEL:
>>> + if (pf->flags & I40E_FLAG_DCB_ENABLED) {
>>> + netdev_info(netdev,
>>> + "Full offload of TC Mqprio options is not supported when DCB is enabled\n");
>>> + return ret;
>>> + }
>>> + if (!(pf->flags & I40E_FLAG_MSIX_ENABLED))
>>> + return ret;
>>> + ret = i40e_validate_mqprio_qopt(vsi, mqprio_qopt);
>>> + if (ret)
>>> + return ret;
>>> + memcpy(&vsi->mqprio_qopt, mqprio_qopt,
>>> + sizeof(*mqprio_qopt));
>>> + pf->flags |= I40E_FLAG_TC_MQPRIO;
>>> + pf->flags &= ~I40E_FLAG_DCB_ENABLED;
>>> + break;
>>> + default:
>>> + return -EINVAL;
>>> }
>>>
>>> +config_tc:
>>> /* Generate TC map for number of tc requested */
>>> - for (i = 0; i < tc; i++)
>>> + for (i = 0; i < num_tc; i++)
>>> enabled_tc |= BIT(i);
>>>
>>> /* Requesting same TC configuration as already enabled */
>>> - if (enabled_tc == vsi->tc_config.enabled_tc)
>>> + if (enabled_tc == vsi->tc_config.enabled_tc &&
>>> + mode != TC_MQPRIO_MODE_CHANNEL)
>>> return 0;
>>>
>>> /* Quiesce VSI queues */
>>> i40e_quiesce_vsi(vsi);
>>>
>>> + if (!hw && !(pf->flags & I40E_FLAG_TC_MQPRIO))
>>> + i40e_remove_queue_channels(vsi);
>>> +
>>> /* Configure VSI for enabled TCs */
>>> ret = i40e_vsi_config_tc(vsi, enabled_tc);
>>> if (ret) {
>>> netdev_info(netdev, "Failed configuring TC for VSI seid=%d\n",
>>> vsi->seid);
>>> + need_reset = true;
>>> goto exit;
>>> }
>>>
>>> @@ -6272,11 +6595,18 @@ static int i40e_setup_tc(struct net_device *netdev, u8 tc)
>>> if (ret) {
>>> netdev_info(netdev,
>>> "Failed configuring queue channels\n");
>>> + need_reset = true;
>>> goto exit;
>>> }
>>> }
>>>
>>> exit:
>>> + /* Reset the configuration data to defaults, only TC0 is enabled */
>>> + if (need_reset) {
>>> + i40e_vsi_set_default_tc_config(vsi);
>>> + need_reset = false;
>>> + }
>>> +
>>> /* Unquiesce VSI */
>>> i40e_unquiesce_vsi(vsi);
>>> return ret;
>>> @@ -6285,14 +6615,10 @@ static int i40e_setup_tc(struct net_device *netdev, u8 tc)
>>> static int __i40e_setup_tc(struct net_device *netdev, enum tc_setup_type type,
>>> void *type_data)
>>> {
>>> - struct tc_mqprio_qopt *mqprio = type_data;
>>> -
>>> if (type != TC_SETUP_MQPRIO)
>>> return -EOPNOTSUPP;
>>>
>>> - mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
>>> -
>>> - return i40e_setup_tc(netdev, mqprio->num_tc);
>>> + return i40e_setup_tc(netdev, type_data);
>>> }
>>>
>>> /**
>>> @@ -9153,45 +9479,6 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)
>>> return err;
>>> }
>>>
>>> -/**
>>> - * i40e_config_rss_aq - Prepare for RSS using AQ commands
>>> - * @vsi: vsi structure
>>> - * @seed: RSS hash seed
>>> - **/
>>> -static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
>>> - u8 *lut, u16 lut_size)
>>> -{
>>> - struct i40e_pf *pf = vsi->back;
>>> - struct i40e_hw *hw = &pf->hw;
>>> - int ret = 0;
>>> -
>>> - if (seed) {
>>> - struct i40e_aqc_get_set_rss_key_data *seed_dw =
>>> - (struct i40e_aqc_get_set_rss_key_data *)seed;
>>> - ret = i40e_aq_set_rss_key(hw, vsi->id, seed_dw);
>>> - if (ret) {
>>> - dev_info(&pf->pdev->dev,
>>> - "Cannot set RSS key, err %s aq_err %s\n",
>>> - i40e_stat_str(hw, ret),
>>> - i40e_aq_str(hw, hw->aq.asq_last_status));
>>> - return ret;
>>> - }
>>> - }
>>> - if (lut) {
>>> - bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false;
>>> -
>>> - ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
>>> - if (ret) {
>>> - dev_info(&pf->pdev->dev,
>>> - "Cannot set RSS lut, err %s aq_err %s\n",
>>> - i40e_stat_str(hw, ret),
>>> - i40e_aq_str(hw, hw->aq.asq_last_status));
>>> - return ret;
>>> - }
>>> - }
>>> - return ret;
>>> -}
>>> -
>>> /**
>>> * i40e_get_rss_aq - Get RSS keys and lut by using AQ commands
>>> * @vsi: Pointer to vsi structure
>>> @@ -9238,46 +9525,6 @@ static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
>>> return ret;
>>> }
>>>
>>> -/**
>>> - * i40e_vsi_config_rss - Prepare for VSI(VMDq) RSS if used
>>> - * @vsi: VSI structure
>>> - **/
>>> -static int i40e_vsi_config_rss(struct i40e_vsi *vsi)
>>> -{
>>> - u8 seed[I40E_HKEY_ARRAY_SIZE];
>>> - struct i40e_pf *pf = vsi->back;
>>> - u8 *lut;
>>> - int ret;
>>> -
>>> - if (!(pf->hw_features & I40E_HW_RSS_AQ_CAPABLE))
>>> - return 0;
>>> -
>>> - if (!vsi->rss_size)
>>> - vsi->rss_size = min_t(int, pf->alloc_rss_size,
>>> - vsi->num_queue_pairs);
>>> - if (!vsi->rss_size)
>>> - return -EINVAL;
>>> -
>>> - lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
>>> - if (!lut)
>>> - return -ENOMEM;
>>> - /* Use the user configured hash keys and lookup table if there is one,
>>> - * otherwise use default
>>> - */
>>> - if (vsi->rss_lut_user)
>>> - memcpy(lut, vsi->rss_lut_user, vsi->rss_table_size);
>>> - else
>>> - i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size);
>>> - if (vsi->rss_hkey_user)
>>> - memcpy(seed, vsi->rss_hkey_user, I40E_HKEY_ARRAY_SIZE);
>>> - else
>>> - netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
>>> - ret = i40e_config_rss_aq(vsi, seed, lut, vsi->rss_table_size);
>>> - kfree(lut);
>>> -
>>> - return ret;
>>> -}
>>> -
>>> /**
>>> * i40e_config_rss_reg - Configure RSS keys and lut by writing registers
>>> * @vsi: Pointer to vsi structure
>>>
>>
>
> .
>
^ permalink raw reply
* [PATCH net-next] tcp: Enable TFO without a cookie on a per-socket basis
From: Christoph Paasch @ 2017-10-17 6:37 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Eric Dumazet, Yuchung Cheng
We already allow to enable TFO without a cookie by using the
fastopen-sysctl and setting it to TFO_SERVER_COOKIE_NOT_REQD (0x200).
This is safe to do in certain environments where we know that there
isn't a malicous host (aka., data-centers).
A server however might be talking to both sides (public Internet and
data-center). So, this server would want to enable cookie-less TFO for
the connections that go to the data-center while enforcing cookies for
the traffic from the Internet.
This patch exposes a socket-option to enable this (protected by
CAP_NET_ADMIN).
Signed-off-by: Christoph Paasch <cpaasch@apple.com>
---
include/linux/tcp.h | 1 +
include/uapi/linux/tcp.h | 1 +
net/ipv4/tcp.c | 14 ++++++++++++++
net/ipv4/tcp_fastopen.c | 6 ++++--
4 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 1d2c44e09e31..cda5d4dc8d70 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -228,6 +228,7 @@ struct tcp_sock {
syn_fastopen_ch:1, /* Active TFO re-enabling probe */
syn_data_acked:1,/* data in SYN is acked by SYN-ACK */
save_syn:1, /* Save headers of SYN packet */
+ no_tfo_cookie:1, /* Allow send/recv SYN+data without a cookie */
is_cwnd_limited:1;/* forward progress limited by snd_cwnd? */
u32 tlp_high_seq; /* snd_nxt at the time of TLP retransmit. */
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
index 15c25eccab2b..d44f4bef056c 100644
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -119,6 +119,7 @@ enum {
#define TCP_FASTOPEN_CONNECT 30 /* Attempt FastOpen with connect */
#define TCP_ULP 31 /* Attach a ULP to a TCP connection */
#define TCP_MD5SIG_EXT 32 /* TCP MD5 Signature with extensions */
+#define TCP_NO_TFO_COOKIE 33 /* Enable TFO without a TFO cookie */
struct tcp_repair_opt {
__u32 opt_code;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 3b34850d361f..88c90be12d9f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2821,6 +2821,16 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
err = -EOPNOTSUPP;
}
break;
+ case TCP_NO_TFO_COOKIE:
+ if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
+ err = -EPERM;
+ else if (val > 1 || val < 0)
+ err = -EINVAL;
+ else if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
+ err = -EINVAL;
+ else
+ tp->no_tfo_cookie = 1;
+ break;
case TCP_TIMESTAMP:
if (!tp->repair)
err = -EPERM;
@@ -3219,6 +3229,10 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
val = tp->fastopen_connect;
break;
+ case TCP_NO_TFO_COOKIE:
+ val = tp->no_tfo_cookie;
+ break;
+
case TCP_TIMESTAMP:
val = tcp_time_stamp_raw() + tp->tsoffset;
break;
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 7ee4aadcdd71..c1b00b666b43 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -309,7 +309,8 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
return NULL;
}
- if (syn_data && (tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD))
+ if (syn_data && ((tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD) ||
+ tcp_sk(sk)->no_tfo_cookie))
goto fastopen;
if (foc->len >= 0 && /* Client presents or requests a cookie */
@@ -363,7 +364,8 @@ bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
return false;
}
- if (sock_net(sk)->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE) {
+ if ((sock_net(sk)->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE) ||
+ tcp_sk(sk)->no_tfo_cookie) {
cookie->len = -1;
return true;
}
--
2.14.1
^ permalink raw reply related
* [PATCH v2 net-next] net: hns3: Add mqprio hardware offload support in hns3 driver
From: Yunsheng Lin @ 2017-10-17 6:51 UTC (permalink / raw)
To: davem
Cc: huangdaode, xuwei5, liguozhu, Yisen.Zhuang, gabriele.paoloni,
john.garry, linuxarm, yisen.zhuang, salil.mehta, lipeng321,
netdev, linux-kernel
When using tc qdisc, dcb_ops->setup_tc is used to tell hclge_dcb
module to do the tm related setup. Only TC_MQPRIO_MODE_CHANNEL
offload mode is supported.
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
---
V2:
1. Add HCLGE_FLAG_MQPRIO_ENABLE to indicate offlaoding the
mqprio.
2. Change to support TC_MQPRIO_MODE_CHANNEL mode.
---
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 +
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 47 +++++++++++++++++-
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 1 +
.../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 56 +++++++++++++++-------
4 files changed, 86 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 575f50d..3acd8db 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -381,6 +381,7 @@ struct hnae3_dcb_ops {
u8 (*setdcbx)(struct hnae3_handle *, u8);
int (*map_update)(struct hnae3_handle *);
+ int (*setup_tc)(struct hnae3_handle *, u8, u8 *);
};
struct hnae3_ae_algo {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
index 1b30a6f..5018d66 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -178,7 +178,8 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)
u8 num_tc = 0;
int ret;
- if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
+ if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
+ hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
return -EINVAL;
ret = hclge_ets_validate(hdev, ets, &num_tc, &map_changed);
@@ -228,7 +229,8 @@ static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
struct hclge_dev *hdev = vport->back;
u8 i, j, pfc_map, *prio_tc;
- if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
+ if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
+ hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
return -EINVAL;
prio_tc = hdev->tm_info.prio_tc;
@@ -257,6 +259,9 @@ static u8 hclge_getdcbx(struct hnae3_handle *h)
struct hclge_vport *vport = hclge_get_vport(h);
struct hclge_dev *hdev = vport->back;
+ if (hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
+ return 0;
+
return hdev->dcbx_cap;
}
@@ -276,6 +281,43 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
return 0;
}
+/* Set up TC for hardware offloaded mqprio in channel mode */
+static int hclge_setup_tc(struct hnae3_handle *h, u8 tc, u8 *prio_tc)
+{
+ struct hclge_vport *vport = hclge_get_vport(h);
+ struct hclge_dev *hdev = vport->back;
+ int ret;
+
+ if (hdev->flag & HCLGE_FLAG_DCB_ENABLE)
+ return -EINVAL;
+
+ if (tc > hdev->tc_max) {
+ dev_err(&hdev->pdev->dev,
+ "setup tc failed, tc(%u) > tc_max(%u)\n",
+ tc, hdev->tc_max);
+ return -EINVAL;
+ }
+
+ hclge_tm_schd_info_update(hdev, tc);
+
+ ret = hclge_tm_prio_tc_info_update(hdev, prio_tc);
+ if (ret)
+ return ret;
+
+ ret = hclge_tm_init_hw(hdev);
+ if (ret)
+ return ret;
+
+ hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
+
+ if (tc > 1)
+ hdev->flag |= HCLGE_FLAG_MQPRIO_ENABLE;
+ else
+ hdev->flag &= ~HCLGE_FLAG_MQPRIO_ENABLE;
+
+ return 0;
+}
+
static const struct hnae3_dcb_ops hns3_dcb_ops = {
.ieee_getets = hclge_ieee_getets,
.ieee_setets = hclge_ieee_setets,
@@ -284,6 +326,7 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
.getdcbx = hclge_getdcbx,
.setdcbx = hclge_setdcbx,
.map_update = hclge_map_update,
+ .setup_tc = hclge_setup_tc,
};
void hclge_dcb_ops_set(struct hclge_dev *hdev)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index a7c018c..bca4430 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -470,6 +470,7 @@ struct hclge_dev {
#define HCLGE_FLAG_MAIN 0x00000004
#define HCLGE_FLAG_DCB_CAPABLE 0x00000008
#define HCLGE_FLAG_DCB_ENABLE 0x00000010
+#define HCLGE_FLAG_MQPRIO_ENABLE 0x00000020
u32 flag;
u32 pkt_buf_size; /* Total pf buf size for tx/rx */
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index ba550c1..8fa4e65 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -19,6 +19,7 @@
#include <linux/sctp.h>
#include <linux/vermagic.h>
#include <net/gre.h>
+#include <net/pkt_cls.h>
#include <net/vxlan.h>
#include "hnae3.h"
@@ -1186,53 +1187,74 @@ static void hns3_nic_udp_tunnel_del(struct net_device *netdev,
}
}
-static int hns3_setup_tc(struct net_device *netdev, u8 tc)
+static int hns3_setup_tc(struct net_device *netdev, void *type_data)
{
+ struct tc_mqprio_qopt_offload *mqprio_qopt = type_data;
struct hnae3_handle *h = hns3_get_handle(netdev);
struct hnae3_knic_private_info *kinfo = &h->kinfo;
+ u8 *prio_tc = mqprio_qopt->qopt.prio_tc_map;
+ u8 tc = mqprio_qopt->qopt.num_tc;
+ u16 mode = mqprio_qopt->mode;
+ u8 hw = mqprio_qopt->qopt.hw;
+ bool if_running;
unsigned int i;
int ret;
+ if (!((hw == TC_MQPRIO_HW_OFFLOAD_TCS &&
+ mode == TC_MQPRIO_MODE_CHANNEL) || (!hw && tc == 0)))
+ return -EOPNOTSUPP;
+
if (tc > HNAE3_MAX_TC)
return -EINVAL;
- if (kinfo->num_tc == tc)
- return 0;
-
if (!netdev)
return -EINVAL;
- if (!tc) {
- netdev_reset_tc(netdev);
- return 0;
+ if_running = netif_running(netdev);
+ if (if_running) {
+ hns3_nic_net_stop(netdev);
+ msleep(100);
}
- /* Set num_tc for netdev */
- ret = netdev_set_num_tc(netdev, tc);
+ ret = (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
+ kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : -EOPNOTSUPP;
if (ret)
- return ret;
+ goto out;
+
+ if (tc <= 1) {
+ netdev_reset_tc(netdev);
+ } else {
+ ret = netdev_set_num_tc(netdev, tc);
+ if (ret)
+ goto out;
+
+ for (i = 0; i < HNAE3_MAX_TC; i++) {
+ if (!kinfo->tc_info[i].enable)
+ continue;
- /* Set per TC queues for the VSI */
- for (i = 0; i < HNAE3_MAX_TC; i++) {
- if (kinfo->tc_info[i].enable)
netdev_set_tc_queue(netdev,
kinfo->tc_info[i].tc,
kinfo->tc_info[i].tqp_count,
kinfo->tc_info[i].tqp_offset);
+ }
}
- return 0;
+ ret = hns3_nic_set_real_num_queue(netdev);
+
+out:
+ if (if_running)
+ hns3_nic_net_open(netdev);
+
+ return ret;
}
static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
- struct tc_mqprio_qopt *mqprio = type_data;
-
if (type != TC_SETUP_MQPRIO)
return -EOPNOTSUPP;
- return hns3_setup_tc(dev, mqprio->num_tc);
+ return hns3_setup_tc(dev, type_data);
}
static int hns3_vlan_rx_add_vid(struct net_device *netdev,
--
1.9.1
^ permalink raw reply related
* [PATCH net-next] qed: Fix iWARP out of order flow
From: Michal Kalderon @ 2017-10-17 7:23 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
dledford-H+wXaHxf7aLQT0dZR+AlfA, Michal Kalderon,
Manish Rangankar, Ariel Elior
Out of order flow is not working for iWARP.
This patch got cut out from initial series that added out
of order support for iWARP.
Make out of order code common for iWARP and iSCSI.
Add new configuration option CONFIG_QED_OOO. Set by
qedr and qedi Kconfigs.
Fixes: d1abfd0b4ee2 ("qed: Add iWARP out of order support")
Signed-off-by: Michal Kalderon <Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
Signed-off-by: Manish Rangankar <Manish.Rangankar-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
Signed-off-by: Ariel Elior <Ariel.Elior-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
drivers/infiniband/hw/qedr/Kconfig | 1 +
drivers/net/ethernet/qlogic/Kconfig | 3 +++
drivers/net/ethernet/qlogic/qed/Makefile | 3 ++-
drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 7 ++++++-
drivers/net/ethernet/qlogic/qed/qed_ooo.c | 16 +++++++++++++---
drivers/net/ethernet/qlogic/qed/qed_ooo.h | 2 +-
drivers/scsi/qedi/Kconfig | 1 +
7 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/hw/qedr/Kconfig b/drivers/infiniband/hw/qedr/Kconfig
index 6c9f392..60e867d 100644
--- a/drivers/infiniband/hw/qedr/Kconfig
+++ b/drivers/infiniband/hw/qedr/Kconfig
@@ -2,6 +2,7 @@ config INFINIBAND_QEDR
tristate "QLogic RoCE driver"
depends on 64BIT && QEDE
select QED_LL2
+ select QED_OOO
select QED_RDMA
---help---
This driver provides low-level InfiniBand over Ethernet
diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig
index c2e24af..26ddf09 100644
--- a/drivers/net/ethernet/qlogic/Kconfig
+++ b/drivers/net/ethernet/qlogic/Kconfig
@@ -117,4 +117,7 @@ config QED_ISCSI
config QED_FCOE
bool
+config QED_OOO
+ bool
+
endif # NET_VENDOR_QLOGIC
diff --git a/drivers/net/ethernet/qlogic/qed/Makefile b/drivers/net/ethernet/qlogic/qed/Makefile
index 82dd470..c3c5999 100644
--- a/drivers/net/ethernet/qlogic/qed/Makefile
+++ b/drivers/net/ethernet/qlogic/qed/Makefile
@@ -6,5 +6,6 @@ qed-y := qed_cxt.o qed_dev.o qed_hw.o qed_init_fw_funcs.o qed_init_ops.o \
qed-$(CONFIG_QED_SRIOV) += qed_sriov.o qed_vf.o
qed-$(CONFIG_QED_LL2) += qed_ll2.o
qed-$(CONFIG_QED_RDMA) += qed_roce.o qed_rdma.o qed_iwarp.o
-qed-$(CONFIG_QED_ISCSI) += qed_iscsi.o qed_ooo.o
+qed-$(CONFIG_QED_ISCSI) += qed_iscsi.o
qed-$(CONFIG_QED_FCOE) += qed_fcoe.o
+qed-$(CONFIG_QED_OOO) += qed_ooo.o
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
index b2b1f87..409041e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
@@ -1410,13 +1410,18 @@ int qed_iwarp_alloc(struct qed_hwfn *p_hwfn)
INIT_LIST_HEAD(&p_hwfn->p_rdma_info->iwarp.ep_free_list);
spin_lock_init(&p_hwfn->p_rdma_info->iwarp.iw_lock);
- return qed_iwarp_prealloc_ep(p_hwfn, true);
+ rc = qed_iwarp_prealloc_ep(p_hwfn, true);
+ if (rc)
+ return rc;
+
+ return qed_ooo_alloc(p_hwfn);
}
void qed_iwarp_resc_free(struct qed_hwfn *p_hwfn)
{
struct qed_iwarp_info *iwarp_info = &p_hwfn->p_rdma_info->iwarp;
+ qed_ooo_free(p_hwfn);
qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->tcp_cid_map, 1);
kfree(iwarp_info->mpa_bufs);
kfree(iwarp_info->partial_fpdus);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ooo.c b/drivers/net/ethernet/qlogic/qed/qed_ooo.c
index 0006365..6172354 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ooo.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ooo.c
@@ -103,18 +103,28 @@ int qed_ooo_alloc(struct qed_hwfn *p_hwfn)
{
u16 max_num_archipelagos = 0, cid_base;
struct qed_ooo_info *p_ooo_info;
+ enum protocol_type proto;
u16 max_num_isles = 0;
u32 i;
- if (p_hwfn->hw_info.personality != QED_PCI_ISCSI) {
+ switch (p_hwfn->hw_info.personality) {
+ case QED_PCI_ISCSI:
+ proto = PROTOCOLID_ISCSI;
+ break;
+ case QED_PCI_ETH_RDMA:
+ case QED_PCI_ETH_IWARP:
+ proto = PROTOCOLID_IWARP;
+ break;
+ default:
DP_NOTICE(p_hwfn,
"Failed to allocate qed_ooo_info: unknown personality\n");
return -EINVAL;
}
- max_num_archipelagos = p_hwfn->pf_params.iscsi_pf_params.num_cons;
+ max_num_archipelagos = (u16)qed_cxt_get_proto_cid_count(p_hwfn, proto,
+ NULL);
max_num_isles = QED_MAX_NUM_ISLES + max_num_archipelagos;
- cid_base = (u16)qed_cxt_get_proto_cid_start(p_hwfn, PROTOCOLID_ISCSI);
+ cid_base = (u16)qed_cxt_get_proto_cid_start(p_hwfn, proto);
if (!max_num_archipelagos) {
DP_NOTICE(p_hwfn,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ooo.h b/drivers/net/ethernet/qlogic/qed/qed_ooo.h
index e8ed40b..49c4e75 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ooo.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_ooo.h
@@ -83,7 +83,7 @@ struct qed_ooo_info {
u16 cid_base;
};
-#if IS_ENABLED(CONFIG_QED_ISCSI)
+#if IS_ENABLED(CONFIG_QED_OOO)
void qed_ooo_save_history_entry(struct qed_hwfn *p_hwfn,
struct qed_ooo_info *p_ooo_info,
struct ooo_opaque *p_cqe);
diff --git a/drivers/scsi/qedi/Kconfig b/drivers/scsi/qedi/Kconfig
index 2ff753c..d1db92d 100644
--- a/drivers/scsi/qedi/Kconfig
+++ b/drivers/scsi/qedi/Kconfig
@@ -4,6 +4,7 @@ config QEDI
depends on QED
select SCSI_ISCSI_ATTRS
select QED_LL2
+ select QED_OOO
select QED_ISCSI
select ISCSI_BOOT_SYSFS
---help---
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH net-next] MAINTAINERS: change ENA driver maintainers email domain
From: netanel @ 2017-10-17 7:30 UTC (permalink / raw)
To: linux-kernel, davem, netdev
Cc: Netanel Belgazal, dwmw, zorik, matua, saeedb, msw, aliguori,
nafea, evgenys
From: Netanel Belgazal <netanel@amazon.com>
ENA driver was developed by developers from Annapurna Labs.
Annapurna Labs was acquired by Amazon and the company's domain
(@annapurnalabs.com) will become deprecated soon.
Update the email addresses of the maintainers to the alternative amazon
emails (@amazon.com)
Signed-off-by: Netanel Belgazal <netanel@amazon.com>
---
MAINTAINERS | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 3944f1626911..f218fe1e43fe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -700,9 +700,9 @@ F: include/linux/altera_uart.h
F: include/linux/altera_jtaguart.h
AMAZON ETHERNET DRIVERS
-M: Netanel Belgazal <netanel@annapurnalabs.com>
-R: Saeed Bishara <saeed@annapurnalabs.com>
-R: Zorik Machulsky <zorik@annapurnalabs.com>
+M: Netanel Belgazal <netanel@amazon.com>
+R: Saeed Bishara <saeedb@amazon.com>
+R: Zorik Machulsky <zorik@amazon.com>
L: netdev@vger.kernel.org
S: Supported
F: Documentation/networking/ena.txt
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 0/3] ENA ethernet driver bug fixes
From: netanel @ 2017-10-17 7:33 UTC (permalink / raw)
To: davem, netdev
Cc: Netanel Belgazal, dwmw, zorik, matua, saeedb, msw, aliguori,
nafea, evgenys
From: Netanel Belgazal <netanel@amazon.com>
Some fixes for ENA ethernet driver
Netanel Belgazal (3):
net: ena: reduce the severity of some printouts
net: ena: fix rare kernel crash when bar memory remap fails
net: ena: fix wrong max Tx/Rx queues on ethtool
drivers/net/ethernet/amazon/ena/ena_ethtool.c | 4 ++--
drivers/net/ethernet/amazon/ena/ena_netdev.c | 7 ++++---
2 files changed, 6 insertions(+), 5 deletions(-)
--
1.8.3.1
^ 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