diff options
author | Jarek Poplawski <jarkao2@gmail.com> | 2008-02-12 00:26:43 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-02-12 20:53:32 -0500 |
commit | 4de211f1a279275c6c67d6e9b6b25513e46b0bb9 (patch) | |
tree | b8e57f1000ed1d5ba0d93a8126a613ca6b3c7a7a /net/ax25 | |
parent | 1105b5d1d44e6f00e31422dfcb0139bc8ae966a9 (diff) |
[AX25] ax25_route: make ax25_route_lock BH safe
> =================================
> [ INFO: inconsistent lock state ]
> 2.6.24-dg8ngn-p02 #1
> ---------------------------------
> inconsistent {softirq-on-W} -> {in-softirq-R} usage.
> linuxnet/3046 [HC0[0]:SC1[2]:HE1:SE0] takes:
> (ax25_route_lock){--.+}, at: [<f8a0cfb7>] ax25_get_route+0x18/0xb7 [ax25]
> {softirq-on-W} state was registered at:
...
This lockdep report shows that ax25_route_lock is taken for reading in
softirq context, and for writing in process context with BHs enabled.
So, to make this safe, all write_locks in ax25_route.c are changed to
_bh versions.
Reported-by: Jann Traschewski <jann@gmx.de>,
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ax25')
-rw-r--r-- | net/ax25/ax25_route.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 38c7f3087ec3..8672cd84fdf9 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c | |||
@@ -45,7 +45,7 @@ void ax25_rt_device_down(struct net_device *dev) | |||
45 | { | 45 | { |
46 | ax25_route *s, *t, *ax25_rt; | 46 | ax25_route *s, *t, *ax25_rt; |
47 | 47 | ||
48 | write_lock(&ax25_route_lock); | 48 | write_lock_bh(&ax25_route_lock); |
49 | ax25_rt = ax25_route_list; | 49 | ax25_rt = ax25_route_list; |
50 | while (ax25_rt != NULL) { | 50 | while (ax25_rt != NULL) { |
51 | s = ax25_rt; | 51 | s = ax25_rt; |
@@ -68,7 +68,7 @@ void ax25_rt_device_down(struct net_device *dev) | |||
68 | } | 68 | } |
69 | } | 69 | } |
70 | } | 70 | } |
71 | write_unlock(&ax25_route_lock); | 71 | write_unlock_bh(&ax25_route_lock); |
72 | } | 72 | } |
73 | 73 | ||
74 | static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | 74 | static int __must_check ax25_rt_add(struct ax25_routes_struct *route) |
@@ -82,7 +82,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
82 | if (route->digi_count > AX25_MAX_DIGIS) | 82 | if (route->digi_count > AX25_MAX_DIGIS) |
83 | return -EINVAL; | 83 | return -EINVAL; |
84 | 84 | ||
85 | write_lock(&ax25_route_lock); | 85 | write_lock_bh(&ax25_route_lock); |
86 | 86 | ||
87 | ax25_rt = ax25_route_list; | 87 | ax25_rt = ax25_route_list; |
88 | while (ax25_rt != NULL) { | 88 | while (ax25_rt != NULL) { |
@@ -92,7 +92,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
92 | ax25_rt->digipeat = NULL; | 92 | ax25_rt->digipeat = NULL; |
93 | if (route->digi_count != 0) { | 93 | if (route->digi_count != 0) { |
94 | if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { | 94 | if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { |
95 | write_unlock(&ax25_route_lock); | 95 | write_unlock_bh(&ax25_route_lock); |
96 | return -ENOMEM; | 96 | return -ENOMEM; |
97 | } | 97 | } |
98 | ax25_rt->digipeat->lastrepeat = -1; | 98 | ax25_rt->digipeat->lastrepeat = -1; |
@@ -102,14 +102,14 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
102 | ax25_rt->digipeat->calls[i] = route->digi_addr[i]; | 102 | ax25_rt->digipeat->calls[i] = route->digi_addr[i]; |
103 | } | 103 | } |
104 | } | 104 | } |
105 | write_unlock(&ax25_route_lock); | 105 | write_unlock_bh(&ax25_route_lock); |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | ax25_rt = ax25_rt->next; | 108 | ax25_rt = ax25_rt->next; |
109 | } | 109 | } |
110 | 110 | ||
111 | if ((ax25_rt = kmalloc(sizeof(ax25_route), GFP_ATOMIC)) == NULL) { | 111 | if ((ax25_rt = kmalloc(sizeof(ax25_route), GFP_ATOMIC)) == NULL) { |
112 | write_unlock(&ax25_route_lock); | 112 | write_unlock_bh(&ax25_route_lock); |
113 | return -ENOMEM; | 113 | return -ENOMEM; |
114 | } | 114 | } |
115 | 115 | ||
@@ -120,7 +120,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
120 | ax25_rt->ip_mode = ' '; | 120 | ax25_rt->ip_mode = ' '; |
121 | if (route->digi_count != 0) { | 121 | if (route->digi_count != 0) { |
122 | if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { | 122 | if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { |
123 | write_unlock(&ax25_route_lock); | 123 | write_unlock_bh(&ax25_route_lock); |
124 | kfree(ax25_rt); | 124 | kfree(ax25_rt); |
125 | return -ENOMEM; | 125 | return -ENOMEM; |
126 | } | 126 | } |
@@ -133,7 +133,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
133 | } | 133 | } |
134 | ax25_rt->next = ax25_route_list; | 134 | ax25_rt->next = ax25_route_list; |
135 | ax25_route_list = ax25_rt; | 135 | ax25_route_list = ax25_rt; |
136 | write_unlock(&ax25_route_lock); | 136 | write_unlock_bh(&ax25_route_lock); |
137 | 137 | ||
138 | return 0; | 138 | return 0; |
139 | } | 139 | } |
@@ -152,7 +152,7 @@ static int ax25_rt_del(struct ax25_routes_struct *route) | |||
152 | if ((ax25_dev = ax25_addr_ax25dev(&route->port_addr)) == NULL) | 152 | if ((ax25_dev = ax25_addr_ax25dev(&route->port_addr)) == NULL) |
153 | return -EINVAL; | 153 | return -EINVAL; |
154 | 154 | ||
155 | write_lock(&ax25_route_lock); | 155 | write_lock_bh(&ax25_route_lock); |
156 | 156 | ||
157 | ax25_rt = ax25_route_list; | 157 | ax25_rt = ax25_route_list; |
158 | while (ax25_rt != NULL) { | 158 | while (ax25_rt != NULL) { |
@@ -174,7 +174,7 @@ static int ax25_rt_del(struct ax25_routes_struct *route) | |||
174 | } | 174 | } |
175 | } | 175 | } |
176 | } | 176 | } |
177 | write_unlock(&ax25_route_lock); | 177 | write_unlock_bh(&ax25_route_lock); |
178 | 178 | ||
179 | return 0; | 179 | return 0; |
180 | } | 180 | } |
@@ -188,7 +188,7 @@ static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option) | |||
188 | if ((ax25_dev = ax25_addr_ax25dev(&rt_option->port_addr)) == NULL) | 188 | if ((ax25_dev = ax25_addr_ax25dev(&rt_option->port_addr)) == NULL) |
189 | return -EINVAL; | 189 | return -EINVAL; |
190 | 190 | ||
191 | write_lock(&ax25_route_lock); | 191 | write_lock_bh(&ax25_route_lock); |
192 | 192 | ||
193 | ax25_rt = ax25_route_list; | 193 | ax25_rt = ax25_route_list; |
194 | while (ax25_rt != NULL) { | 194 | while (ax25_rt != NULL) { |
@@ -216,7 +216,7 @@ static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | out: | 218 | out: |
219 | write_unlock(&ax25_route_lock); | 219 | write_unlock_bh(&ax25_route_lock); |
220 | return err; | 220 | return err; |
221 | } | 221 | } |
222 | 222 | ||
@@ -492,7 +492,7 @@ void __exit ax25_rt_free(void) | |||
492 | { | 492 | { |
493 | ax25_route *s, *ax25_rt = ax25_route_list; | 493 | ax25_route *s, *ax25_rt = ax25_route_list; |
494 | 494 | ||
495 | write_lock(&ax25_route_lock); | 495 | write_lock_bh(&ax25_route_lock); |
496 | while (ax25_rt != NULL) { | 496 | while (ax25_rt != NULL) { |
497 | s = ax25_rt; | 497 | s = ax25_rt; |
498 | ax25_rt = ax25_rt->next; | 498 | ax25_rt = ax25_rt->next; |
@@ -500,5 +500,5 @@ void __exit ax25_rt_free(void) | |||
500 | kfree(s->digipeat); | 500 | kfree(s->digipeat); |
501 | kfree(s); | 501 | kfree(s); |
502 | } | 502 | } |
503 | write_unlock(&ax25_route_lock); | 503 | write_unlock_bh(&ax25_route_lock); |
504 | } | 504 | } |