Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
f987ed6e
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看板
提交
f987ed6e
编写于
12月 12, 2010
作者:
M
Marek Lindner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
batman-adv: protect neighbor list with rcu locks
Signed-off-by:
N
Marek Lindner
<
lindner_marek@yahoo.de
>
上级
9591a79f
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
57 addition
and
21 deletion
+57
-21
net/batman-adv/originator.c
net/batman-adv/originator.c
+28
-7
net/batman-adv/routing.c
net/batman-adv/routing.c
+27
-14
net/batman-adv/types.h
net/batman-adv/types.h
+2
-0
未找到文件。
net/batman-adv/originator.c
浏览文件 @
f987ed6e
...
...
@@ -67,6 +67,14 @@ void neigh_node_free_ref(struct kref *refcount)
kfree
(
neigh_node
);
}
static
void
neigh_node_free_rcu
(
struct
rcu_head
*
rcu
)
{
struct
neigh_node
*
neigh_node
;
neigh_node
=
container_of
(
rcu
,
struct
neigh_node
,
rcu
);
kref_put
(
&
neigh_node
->
refcount
,
neigh_node_free_ref
);
}
struct
neigh_node
*
create_neighbor
(
struct
orig_node
*
orig_node
,
struct
orig_node
*
orig_neigh_node
,
uint8_t
*
neigh
,
...
...
@@ -89,7 +97,9 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
neigh_node
->
if_incoming
=
if_incoming
;
kref_init
(
&
neigh_node
->
refcount
);
hlist_add_head
(
&
neigh_node
->
list
,
&
orig_node
->
neigh_list
);
spin_lock_bh
(
&
orig_node
->
neigh_list_lock
);
hlist_add_head_rcu
(
&
neigh_node
->
list
,
&
orig_node
->
neigh_list
);
spin_unlock_bh
(
&
orig_node
->
neigh_list_lock
);
return
neigh_node
;
}
...
...
@@ -100,13 +110,17 @@ static void free_orig_node(void *data, void *arg)
struct
orig_node
*
orig_node
=
(
struct
orig_node
*
)
data
;
struct
bat_priv
*
bat_priv
=
(
struct
bat_priv
*
)
arg
;
spin_lock_bh
(
&
orig_node
->
neigh_list_lock
);
/* for all neighbors towards this originator ... */
hlist_for_each_entry_safe
(
neigh_node
,
node
,
node_tmp
,
&
orig_node
->
neigh_list
,
list
)
{
hlist_del
(
&
neigh_node
->
list
);
kref_put
(
&
neigh_node
->
refcount
,
neigh_node_free_ref
);
hlist_del
_rcu
(
&
neigh_node
->
list
);
call_rcu
(
&
neigh_node
->
rcu
,
neigh_node_free_rcu
);
}
spin_unlock_bh
(
&
orig_node
->
neigh_list_lock
);
frag_list_free
(
&
orig_node
->
frag_list
);
hna_global_del_orig
(
bat_priv
,
orig_node
,
"originator timed out"
);
...
...
@@ -151,6 +165,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
return
NULL
;
INIT_HLIST_HEAD
(
&
orig_node
->
neigh_list
);
spin_lock_init
(
&
orig_node
->
neigh_list_lock
);
memcpy
(
orig_node
->
orig
,
addr
,
ETH_ALEN
);
orig_node
->
router
=
NULL
;
...
...
@@ -200,6 +215,8 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv,
*
best_neigh_node
=
NULL
;
spin_lock_bh
(
&
orig_node
->
neigh_list_lock
);
/* for all neighbors towards this originator ... */
hlist_for_each_entry_safe
(
neigh_node
,
node
,
node_tmp
,
&
orig_node
->
neigh_list
,
list
)
{
...
...
@@ -225,14 +242,16 @@ static bool purge_orig_neighbors(struct bat_priv *bat_priv,
neigh_purged
=
true
;
hlist_del
(
&
neigh_node
->
list
);
kref_put
(
&
neigh_node
->
refcount
,
neigh_node_free_ref
);
hlist_del
_rcu
(
&
neigh_node
->
list
);
call_rcu
(
&
neigh_node
->
rcu
,
neigh_node_free_rcu
);
}
else
{
if
((
!*
best_neigh_node
)
||
(
neigh_node
->
tq_avg
>
(
*
best_neigh_node
)
->
tq_avg
))
*
best_neigh_node
=
neigh_node
;
}
}
spin_unlock_bh
(
&
orig_node
->
neigh_list_lock
);
return
neigh_purged
;
}
...
...
@@ -384,11 +403,13 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
neigh_node
->
addr
,
neigh_node
->
if_incoming
->
net_dev
->
name
);
hlist_for_each_entry
(
neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
rcu_read_lock
();
hlist_for_each_entry_rcu
(
neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
seq_printf
(
seq
,
" %pM (%3i)"
,
neigh_node
->
addr
,
neigh_node
->
tq_avg
);
}
rcu_read_unlock
();
seq_printf
(
seq
,
"
\n
"
);
batman_count
++
;
...
...
net/batman-adv/routing.c
浏览文件 @
f987ed6e
...
...
@@ -153,14 +153,16 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
unsigned
char
total_count
;
if
(
orig_node
==
orig_neigh_node
)
{
hlist_for_each_entry
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
if
(
compare_orig
(
tmp_neigh_node
->
addr
,
orig_neigh_node
->
orig
)
&&
(
tmp_neigh_node
->
if_incoming
==
if_incoming
))
neigh_node
=
tmp_neigh_node
;
}
rcu_read_unlock
();
if
(
!
neigh_node
)
neigh_node
=
create_neighbor
(
orig_node
,
...
...
@@ -174,14 +176,16 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
neigh_node
->
last_valid
=
jiffies
;
}
else
{
/* find packet count of corresponding one hop neighbor */
hlist_for_each_entry
(
tmp_neigh_node
,
node
,
&
orig_neigh_node
->
neigh_list
,
list
)
{
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tmp_neigh_node
,
node
,
&
orig_neigh_node
->
neigh_list
,
list
)
{
if
(
compare_orig
(
tmp_neigh_node
->
addr
,
orig_neigh_node
->
orig
)
&&
(
tmp_neigh_node
->
if_incoming
==
if_incoming
))
neigh_node
=
tmp_neigh_node
;
}
rcu_read_unlock
();
if
(
!
neigh_node
)
neigh_node
=
create_neighbor
(
orig_neigh_node
,
...
...
@@ -266,8 +270,9 @@ static void update_orig(struct bat_priv *bat_priv,
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"update_originator(): "
"Searching and updating originator entry of received packet
\n
"
);
hlist_for_each_entry
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
if
(
compare_orig
(
tmp_neigh_node
->
addr
,
ethhdr
->
h_source
)
&&
(
tmp_neigh_node
->
if_incoming
==
if_incoming
))
{
neigh_node
=
tmp_neigh_node
;
...
...
@@ -282,6 +287,7 @@ static void update_orig(struct bat_priv *bat_priv,
tmp_neigh_node
->
tq_avg
=
ring_buffer_avg
(
tmp_neigh_node
->
tq_recv
);
}
rcu_read_unlock
();
if
(
!
neigh_node
)
{
struct
orig_node
*
orig_tmp
;
...
...
@@ -410,8 +416,9 @@ static char count_real_packets(struct ethhdr *ethhdr,
&
orig_node
->
batman_seqno_reset
))
return
-
1
;
hlist_for_each_entry
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
is_duplicate
|=
get_bit_status
(
tmp_neigh_node
->
real_bits
,
orig_node
->
last_real_seqno
,
...
...
@@ -431,6 +438,7 @@ static char count_real_packets(struct ethhdr *ethhdr,
tmp_neigh_node
->
real_packet_count
=
bit_packet_count
(
tmp_neigh_node
->
real_bits
);
}
rcu_read_unlock
();
if
(
need_update
)
{
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
...
...
@@ -481,15 +489,19 @@ void update_bonding_candidates(struct orig_node *orig_node)
* as "bonding partner" */
/* first, zero the list */
hlist_for_each_entry
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
tmp_neigh_node
->
next_bond_candidate
=
NULL
;
}
rcu_read_unlock
();
first_candidate
=
NULL
;
last_candidate
=
NULL
;
hlist_for_each_entry
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tmp_neigh_node
,
node
,
&
orig_node
->
neigh_list
,
list
)
{
/* only consider if it has the same primary address ... */
if
(
memcmp
(
orig_node
->
orig
,
...
...
@@ -506,8 +518,8 @@ void update_bonding_candidates(struct orig_node *orig_node)
* select this candidate because of possible interference. */
interference_candidate
=
0
;
hlist_for_each_entry
(
tmp_neigh_node2
,
node2
,
&
orig_node
->
neigh_list
,
list
)
{
hlist_for_each_entry
_rcu
(
tmp_neigh_node2
,
node2
,
&
orig_node
->
neigh_list
,
list
)
{
if
(
tmp_neigh_node2
==
tmp_neigh_node
)
continue
;
...
...
@@ -541,6 +553,7 @@ void update_bonding_candidates(struct orig_node *orig_node)
candidates
++
;
}
rcu_read_unlock
();
if
(
candidates
>
0
)
{
first_candidate
->
next_bond_candidate
=
last_candidate
;
...
...
net/batman-adv/types.h
浏览文件 @
f987ed6e
...
...
@@ -85,6 +85,7 @@ struct orig_node {
uint32_t
last_bcast_seqno
;
struct
hlist_head
neigh_list
;
struct
list_head
frag_list
;
spinlock_t
neigh_list_lock
;
/* protects neighbor list */
unsigned
long
last_frag_packet
;
struct
{
uint8_t
candidates
;
...
...
@@ -116,6 +117,7 @@ struct neigh_node {
unsigned
long
last_valid
;
unsigned
long
real_bits
[
NUM_WORDS
];
struct
kref
refcount
;
struct
rcu_head
rcu
;
struct
orig_node
*
orig_node
;
struct
batman_if
*
if_incoming
;
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录