Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
6accec76
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 3 年多
通知
13
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
6accec76
编写于
7月 18, 2010
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sch_atm: Convert to use standard list_head facilities.
Signed-off-by:
N
David S. Miller
<
davem@davemloft.net
>
上级
c1f19b51
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
41 addition
and
57 deletion
+41
-57
net/sched/sch_atm.c
net/sched/sch_atm.c
+41
-57
未找到文件。
net/sched/sch_atm.c
浏览文件 @
6accec76
...
...
@@ -52,7 +52,7 @@ struct atm_flow_data {
int
ref
;
/* reference count */
struct
gnet_stats_basic_packed
bstats
;
struct
gnet_stats_queue
qstats
;
struct
atm_flow_data
*
nex
t
;
struct
list_head
lis
t
;
struct
atm_flow_data
*
excess
;
/* flow for excess traffic;
NULL to set CLP instead */
int
hdr_len
;
...
...
@@ -61,34 +61,23 @@ struct atm_flow_data {
struct
atm_qdisc_data
{
struct
atm_flow_data
link
;
/* unclassified skbs go here */
struct
atm_flow_data
*
flows
;
/* NB: "link" is also on this
struct
list_head
flows
;
/* NB: "link" is also on this
list */
struct
tasklet_struct
task
;
/* dequeue tasklet */
};
/* ------------------------- Class/flow operations ------------------------- */
static
int
find_flow
(
struct
atm_qdisc_data
*
qdisc
,
struct
atm_flow_data
*
flow
)
{
struct
atm_flow_data
*
walk
;
pr_debug
(
"find_flow(qdisc %p,flow %p)
\n
"
,
qdisc
,
flow
);
for
(
walk
=
qdisc
->
flows
;
walk
;
walk
=
walk
->
next
)
if
(
walk
==
flow
)
return
1
;
pr_debug
(
"find_flow: not found
\n
"
);
return
0
;
}
static
inline
struct
atm_flow_data
*
lookup_flow
(
struct
Qdisc
*
sch
,
u32
classid
)
{
struct
atm_qdisc_data
*
p
=
qdisc_priv
(
sch
);
struct
atm_flow_data
*
flow
;
for
(
flow
=
p
->
flows
;
flow
;
flow
=
flow
->
next
)
list_for_each_entry
(
flow
,
&
p
->
flows
,
list
)
{
if
(
flow
->
classid
==
classid
)
break
;
return
flow
;
return
flow
;
}
return
NULL
;
}
static
int
atm_tc_graft
(
struct
Qdisc
*
sch
,
unsigned
long
arg
,
...
...
@@ -99,7 +88,7 @@ static int atm_tc_graft(struct Qdisc *sch, unsigned long arg,
pr_debug
(
"atm_tc_graft(sch %p,[qdisc %p],flow %p,new %p,old %p)
\n
"
,
sch
,
p
,
flow
,
new
,
old
);
if
(
!
find_flow
(
p
,
flow
))
if
(
list_empty
(
&
flow
->
list
))
return
-
EINVAL
;
if
(
!
new
)
new
=
&
noop_qdisc
;
...
...
@@ -146,20 +135,12 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
{
struct
atm_qdisc_data
*
p
=
qdisc_priv
(
sch
);
struct
atm_flow_data
*
flow
=
(
struct
atm_flow_data
*
)
cl
;
struct
atm_flow_data
**
prev
;
pr_debug
(
"atm_tc_put(sch %p,[qdisc %p],flow %p)
\n
"
,
sch
,
p
,
flow
);
if
(
--
flow
->
ref
)
return
;
pr_debug
(
"atm_tc_put: destroying
\n
"
);
for
(
prev
=
&
p
->
flows
;
*
prev
;
prev
=
&
(
*
prev
)
->
next
)
if
(
*
prev
==
flow
)
break
;
if
(
!*
prev
)
{
printk
(
KERN_CRIT
"atm_tc_put: class %p not found
\n
"
,
flow
);
return
;
}
*
prev
=
flow
->
next
;
list_del_init
(
&
flow
->
list
);
pr_debug
(
"atm_tc_put: qdisc %p
\n
"
,
flow
->
q
);
qdisc_destroy
(
flow
->
q
);
tcf_destroy_chain
(
&
flow
->
filter_list
);
...
...
@@ -274,7 +255,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
error
=
-
EINVAL
;
goto
err_out
;
}
if
(
find_flow
(
p
,
flow
))
{
if
(
!
list_empty
(
&
flow
->
list
))
{
error
=
-
EEXIST
;
goto
err_out
;
}
...
...
@@ -313,8 +294,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
flow
->
classid
=
classid
;
flow
->
ref
=
1
;
flow
->
excess
=
excess
;
flow
->
next
=
p
->
link
.
next
;
p
->
link
.
next
=
flow
;
list_add
(
&
flow
->
list
,
&
p
->
link
.
list
);
flow
->
hdr_len
=
hdr_len
;
if
(
hdr
)
memcpy
(
flow
->
hdr
,
hdr
,
hdr_len
);
...
...
@@ -335,7 +315,7 @@ static int atm_tc_delete(struct Qdisc *sch, unsigned long arg)
struct
atm_flow_data
*
flow
=
(
struct
atm_flow_data
*
)
arg
;
pr_debug
(
"atm_tc_delete(sch %p,[qdisc %p],flow %p)
\n
"
,
sch
,
p
,
flow
);
if
(
!
find_flow
(
qdisc_priv
(
sch
),
flow
))
if
(
list_empty
(
&
flow
->
list
))
return
-
EINVAL
;
if
(
flow
->
filter_list
||
flow
==
&
p
->
link
)
return
-
EBUSY
;
...
...
@@ -361,12 +341,12 @@ static void atm_tc_walk(struct Qdisc *sch, struct qdisc_walker *walker)
pr_debug
(
"atm_tc_walk(sch %p,[qdisc %p],walker %p)
\n
"
,
sch
,
p
,
walker
);
if
(
walker
->
stop
)
return
;
for
(
flow
=
p
->
flows
;
flow
;
flow
=
flow
->
nex
t
)
{
if
(
walker
->
count
>=
walker
->
skip
)
if
(
walker
->
fn
(
sch
,
(
unsigned
long
)
flow
,
walker
)
<
0
)
{
walker
->
stop
=
1
;
break
;
}
list_for_each_entry
(
flow
,
&
p
->
flows
,
lis
t
)
{
if
(
walker
->
count
>=
walker
->
skip
&&
walker
->
fn
(
sch
,
(
unsigned
long
)
flow
,
walker
)
<
0
)
{
walker
->
stop
=
1
;
break
;
}
walker
->
count
++
;
}
}
...
...
@@ -385,16 +365,17 @@ static struct tcf_proto **atm_tc_find_tcf(struct Qdisc *sch, unsigned long cl)
static
int
atm_tc_enqueue
(
struct
sk_buff
*
skb
,
struct
Qdisc
*
sch
)
{
struct
atm_qdisc_data
*
p
=
qdisc_priv
(
sch
);
struct
atm_flow_data
*
flow
=
NULL
;
/* @@@ */
struct
atm_flow_data
*
flow
;
struct
tcf_result
res
;
int
result
;
int
ret
=
NET_XMIT_POLICED
;
pr_debug
(
"atm_tc_enqueue(skb %p,sch %p,[qdisc %p])
\n
"
,
skb
,
sch
,
p
);
result
=
TC_POLICE_OK
;
/* be nice to gcc */
flow
=
NULL
;
if
(
TC_H_MAJ
(
skb
->
priority
)
!=
sch
->
handle
||
!
(
flow
=
(
struct
atm_flow_data
*
)
atm_tc_get
(
sch
,
skb
->
priority
)))
for
(
flow
=
p
->
flows
;
flow
;
flow
=
flow
->
next
)
!
(
flow
=
(
struct
atm_flow_data
*
)
atm_tc_get
(
sch
,
skb
->
priority
)))
{
list_for_each_entry
(
flow
,
&
p
->
flows
,
list
)
{
if
(
flow
->
filter_list
)
{
result
=
tc_classify_compat
(
skb
,
flow
->
filter_list
,
...
...
@@ -404,8 +385,13 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
flow
=
(
struct
atm_flow_data
*
)
res
.
class
;
if
(
!
flow
)
flow
=
lookup_flow
(
sch
,
res
.
classid
);
break
;
goto
done
;
}
}
flow
=
NULL
;
done:
;
}
if
(
!
flow
)
flow
=
&
p
->
link
;
else
{
...
...
@@ -477,7 +463,9 @@ static void sch_atm_dequeue(unsigned long data)
struct
sk_buff
*
skb
;
pr_debug
(
"sch_atm_dequeue(sch %p,[qdisc %p])
\n
"
,
sch
,
p
);
for
(
flow
=
p
->
link
.
next
;
flow
;
flow
=
flow
->
next
)
list_for_each_entry
(
flow
,
&
p
->
flows
,
list
)
{
if
(
flow
==
&
p
->
link
)
continue
;
/*
* If traffic is properly shaped, this won't generate nasty
* little bursts. Otherwise, it may ... (but that's okay)
...
...
@@ -512,6 +500,7 @@ static void sch_atm_dequeue(unsigned long data)
/* atm.atm_options are already set by atm_tc_enqueue */
flow
->
vcc
->
send
(
flow
->
vcc
,
skb
);
}
}
}
static
struct
sk_buff
*
atm_tc_dequeue
(
struct
Qdisc
*
sch
)
...
...
@@ -543,9 +532,10 @@ static unsigned int atm_tc_drop(struct Qdisc *sch)
unsigned
int
len
;
pr_debug
(
"atm_tc_drop(sch %p,[qdisc %p])
\n
"
,
sch
,
p
);
for
(
flow
=
p
->
flows
;
flow
;
flow
=
flow
->
next
)
list_for_each_entry
(
flow
,
&
p
->
flows
,
list
)
{
if
(
flow
->
q
->
ops
->
drop
&&
(
len
=
flow
->
q
->
ops
->
drop
(
flow
->
q
)))
return
len
;
}
return
0
;
}
...
...
@@ -554,7 +544,9 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
struct
atm_qdisc_data
*
p
=
qdisc_priv
(
sch
);
pr_debug
(
"atm_tc_init(sch %p,[qdisc %p],opt %p)
\n
"
,
sch
,
p
,
opt
);
p
->
flows
=
&
p
->
link
;
INIT_LIST_HEAD
(
&
p
->
flows
);
INIT_LIST_HEAD
(
&
p
->
link
.
list
);
list_add
(
&
p
->
link
.
list
,
&
p
->
flows
);
p
->
link
.
q
=
qdisc_create_dflt
(
qdisc_dev
(
sch
),
sch
->
dev_queue
,
&
pfifo_qdisc_ops
,
sch
->
handle
);
if
(
!
p
->
link
.
q
)
...
...
@@ -565,7 +557,6 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
p
->
link
.
sock
=
NULL
;
p
->
link
.
classid
=
sch
->
handle
;
p
->
link
.
ref
=
1
;
p
->
link
.
next
=
NULL
;
tasklet_init
(
&
p
->
task
,
sch_atm_dequeue
,
(
unsigned
long
)
sch
);
return
0
;
}
...
...
@@ -576,7 +567,7 @@ static void atm_tc_reset(struct Qdisc *sch)
struct
atm_flow_data
*
flow
;
pr_debug
(
"atm_tc_reset(sch %p,[qdisc %p])
\n
"
,
sch
,
p
);
for
(
flow
=
p
->
flows
;
flow
;
flow
=
flow
->
nex
t
)
list_for_each_entry
(
flow
,
&
p
->
flows
,
lis
t
)
qdisc_reset
(
flow
->
q
);
sch
->
q
.
qlen
=
0
;
}
...
...
@@ -584,24 +575,17 @@ static void atm_tc_reset(struct Qdisc *sch)
static
void
atm_tc_destroy
(
struct
Qdisc
*
sch
)
{
struct
atm_qdisc_data
*
p
=
qdisc_priv
(
sch
);
struct
atm_flow_data
*
flow
;
struct
atm_flow_data
*
flow
,
*
tmp
;
pr_debug
(
"atm_tc_destroy(sch %p,[qdisc %p])
\n
"
,
sch
,
p
);
for
(
flow
=
p
->
flows
;
flow
;
flow
=
flow
->
nex
t
)
list_for_each_entry
(
flow
,
&
p
->
flows
,
lis
t
)
tcf_destroy_chain
(
&
flow
->
filter_list
);
/* races ? */
while
((
flow
=
p
->
flows
))
{
list_for_each_entry_safe
(
flow
,
tmp
,
&
p
->
flows
,
list
)
{
if
(
flow
->
ref
>
1
)
printk
(
KERN_ERR
"atm_destroy: %p->ref = %d
\n
"
,
flow
,
flow
->
ref
);
atm_tc_put
(
sch
,
(
unsigned
long
)
flow
);
if
(
p
->
flows
==
flow
)
{
printk
(
KERN_ERR
"atm_destroy: putting flow %p didn't "
"kill it
\n
"
,
flow
);
p
->
flows
=
flow
->
next
;
/* brute force */
break
;
}
}
tasklet_kill
(
&
p
->
task
);
}
...
...
@@ -615,7 +599,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
pr_debug
(
"atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)
\n
"
,
sch
,
p
,
flow
,
skb
,
tcm
);
if
(
!
find_flow
(
p
,
flow
))
if
(
list_empty
(
&
flow
->
list
))
return
-
EINVAL
;
tcm
->
tcm_handle
=
flow
->
classid
;
tcm
->
tcm_info
=
flow
->
q
->
handle
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录