diff options
author | Linus Luessing <linus.luessing@web.de> | 2010-02-19 10:18:08 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-03 19:43:02 -0500 |
commit | 837b8248f6206a6b08b3d6defe2946282e432679 (patch) | |
tree | cb17aef52d0578dea091365c26656712abd8b087 /drivers | |
parent | bc0ad071a788625abb23aee4cb3c07d17d501641 (diff) |
Staging: batman-adv: atomic variable for vis-srv activation
This fixes the bug discovered by Marek Lindner which did not allow
turning on the vis-server before an interface has been added. With this
patch we are using a global atomic variable for activating and
deactiating the vis-server-mode, which can be used before
inserting an interface.
Signed-off-by: Linus Luessing <linus.luessing@web.de>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/batman-adv/main.c | 2 | ||||
-rw-r--r-- | drivers/staging/batman-adv/main.h | 1 | ||||
-rw-r--r-- | drivers/staging/batman-adv/proc.c | 15 | ||||
-rw-r--r-- | drivers/staging/batman-adv/send.c | 3 | ||||
-rw-r--r-- | drivers/staging/batman-adv/vis.c | 46 | ||||
-rw-r--r-- | drivers/staging/batman-adv/vis.h | 2 |
6 files changed, 18 insertions, 51 deletions
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 3f780753a2bf..2e0b482e710a 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c | |||
@@ -43,6 +43,7 @@ DEFINE_SPINLOCK(forw_bcast_list_lock); | |||
43 | 43 | ||
44 | atomic_t originator_interval; | 44 | atomic_t originator_interval; |
45 | atomic_t vis_interval; | 45 | atomic_t vis_interval; |
46 | atomic_t vis_mode; | ||
46 | atomic_t aggregation_enabled; | 47 | atomic_t aggregation_enabled; |
47 | int16_t num_hna; | 48 | int16_t num_hna; |
48 | int16_t num_ifs; | 49 | int16_t num_ifs; |
@@ -83,6 +84,7 @@ int init_module(void) | |||
83 | atomic_set(&originator_interval, 1000); | 84 | atomic_set(&originator_interval, 1000); |
84 | atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only | 85 | atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only |
85 | * for debugging now. */ | 86 | * for debugging now. */ |
87 | atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE); | ||
86 | atomic_set(&aggregation_enabled, 1); | 88 | atomic_set(&aggregation_enabled, 1); |
87 | 89 | ||
88 | /* the name should not be longer than 10 chars - see | 90 | /* the name should not be longer than 10 chars - see |
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index eb6a702c6444..deb41f5beda6 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h | |||
@@ -130,6 +130,7 @@ extern spinlock_t forw_bcast_list_lock; | |||
130 | 130 | ||
131 | extern atomic_t originator_interval; | 131 | extern atomic_t originator_interval; |
132 | extern atomic_t vis_interval; | 132 | extern atomic_t vis_interval; |
133 | extern atomic_t vis_mode; | ||
133 | extern atomic_t aggregation_enabled; | 134 | extern atomic_t aggregation_enabled; |
134 | extern int16_t num_hna; | 135 | extern int16_t num_hna; |
135 | extern int16_t num_ifs; | 136 | extern int16_t num_ifs; |
diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index 68c36b097a07..0eadc6b48d75 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c | |||
@@ -338,11 +338,11 @@ static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer, | |||
338 | if ((strcmp(vis_mode_string, "client") == 0) || | 338 | if ((strcmp(vis_mode_string, "client") == 0) || |
339 | (strcmp(vis_mode_string, "disabled") == 0)) { | 339 | (strcmp(vis_mode_string, "disabled") == 0)) { |
340 | printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n"); | 340 | printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n"); |
341 | vis_set_mode(VIS_TYPE_CLIENT_UPDATE); | 341 | atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE); |
342 | } else if ((strcmp(vis_mode_string, "server") == 0) || | 342 | } else if ((strcmp(vis_mode_string, "server") == 0) || |
343 | (strcmp(vis_mode_string, "enabled") == 0)) { | 343 | (strcmp(vis_mode_string, "enabled") == 0)) { |
344 | printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n"); | 344 | printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n"); |
345 | vis_set_mode(VIS_TYPE_SERVER_SYNC); | 345 | atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC); |
346 | } else | 346 | } else |
347 | printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n", | 347 | printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n", |
348 | vis_mode_string); | 348 | vis_mode_string); |
@@ -353,12 +353,12 @@ static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer, | |||
353 | 353 | ||
354 | static int proc_vis_srv_read(struct seq_file *seq, void *offset) | 354 | static int proc_vis_srv_read(struct seq_file *seq, void *offset) |
355 | { | 355 | { |
356 | int vis_server = is_vis_server(); | 356 | int vis_server = atomic_read(&vis_mode); |
357 | 357 | ||
358 | seq_printf(seq, "[%c] client mode (server disabled) \n", | 358 | seq_printf(seq, "[%c] client mode (server disabled) \n", |
359 | (!vis_server) ? 'x' : ' '); | 359 | (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' '); |
360 | seq_printf(seq, "[%c] server mode (server enabled) \n", | 360 | seq_printf(seq, "[%c] server mode (server enabled) \n", |
361 | (vis_server) ? 'x' : ' '); | 361 | (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' '); |
362 | 362 | ||
363 | return 0; | 363 | return 0; |
364 | } | 364 | } |
@@ -377,9 +377,10 @@ static int proc_vis_data_read(struct seq_file *seq, void *offset) | |||
377 | int i; | 377 | int i; |
378 | char tmp_addr_str[ETH_STR_LEN]; | 378 | char tmp_addr_str[ETH_STR_LEN]; |
379 | unsigned long flags; | 379 | unsigned long flags; |
380 | int vis_server = atomic_read(&vis_mode); | ||
380 | 381 | ||
381 | rcu_read_lock(); | 382 | rcu_read_lock(); |
382 | if (list_empty(&if_list) || (!is_vis_server())) { | 383 | if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) { |
383 | rcu_read_unlock(); | 384 | rcu_read_unlock(); |
384 | goto end; | 385 | goto end; |
385 | } | 386 | } |
@@ -672,5 +673,3 @@ int setup_procfs(void) | |||
672 | 673 | ||
673 | return 0; | 674 | return 0; |
674 | } | 675 | } |
675 | |||
676 | |||
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 944b2cdbdff8..2a9fac8c240e 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c | |||
@@ -248,6 +248,7 @@ void schedule_own_packet(struct batman_if *batman_if) | |||
248 | { | 248 | { |
249 | unsigned long send_time; | 249 | unsigned long send_time; |
250 | struct batman_packet *batman_packet; | 250 | struct batman_packet *batman_packet; |
251 | int vis_server = atomic_read(&vis_mode); | ||
251 | 252 | ||
252 | /** | 253 | /** |
253 | * the interface gets activated here to avoid race conditions between | 254 | * the interface gets activated here to avoid race conditions between |
@@ -272,7 +273,7 @@ void schedule_own_packet(struct batman_if *batman_if) | |||
272 | /* change sequence number to network order */ | 273 | /* change sequence number to network order */ |
273 | batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno)); | 274 | batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno)); |
274 | 275 | ||
275 | if (is_vis_server()) | 276 | if (vis_server == VIS_TYPE_SERVER_SYNC) |
276 | batman_packet->flags = VIS_SERVER; | 277 | batman_packet->flags = VIS_SERVER; |
277 | else | 278 | else |
278 | batman_packet->flags = 0; | 279 | batman_packet->flags = 0; |
diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index ec8bb3f382c6..fedec1bb3097 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c | |||
@@ -48,41 +48,6 @@ static void free_info(void *data) | |||
48 | kfree(info); | 48 | kfree(info); |
49 | } | 49 | } |
50 | 50 | ||
51 | /* set the mode of the visualization to client or server */ | ||
52 | void vis_set_mode(int mode) | ||
53 | { | ||
54 | unsigned long flags; | ||
55 | spin_lock_irqsave(&vis_hash_lock, flags); | ||
56 | |||
57 | if (my_vis_info != NULL) | ||
58 | my_vis_info->packet.vis_type = mode; | ||
59 | |||
60 | spin_unlock_irqrestore(&vis_hash_lock, flags); | ||
61 | } | ||
62 | |||
63 | /* is_vis_server(), locked outside */ | ||
64 | static int is_vis_server_locked(void) | ||
65 | { | ||
66 | if (my_vis_info != NULL) | ||
67 | if (my_vis_info->packet.vis_type == VIS_TYPE_SERVER_SYNC) | ||
68 | return 1; | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | /* get the current set mode */ | ||
74 | int is_vis_server(void) | ||
75 | { | ||
76 | int ret = 0; | ||
77 | unsigned long flags; | ||
78 | |||
79 | spin_lock_irqsave(&vis_hash_lock, flags); | ||
80 | ret = is_vis_server_locked(); | ||
81 | spin_unlock_irqrestore(&vis_hash_lock, flags); | ||
82 | |||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | /* Compare two vis packets, used by the hashing algorithm */ | 51 | /* Compare two vis packets, used by the hashing algorithm */ |
87 | static int vis_info_cmp(void *data1, void *data2) | 52 | static int vis_info_cmp(void *data1, void *data2) |
88 | { | 53 | { |
@@ -271,6 +236,7 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len) | |||
271 | struct vis_info *info; | 236 | struct vis_info *info; |
272 | int is_new; | 237 | int is_new; |
273 | unsigned long flags; | 238 | unsigned long flags; |
239 | int vis_server = atomic_read(&vis_mode); | ||
274 | 240 | ||
275 | spin_lock_irqsave(&vis_hash_lock, flags); | 241 | spin_lock_irqsave(&vis_hash_lock, flags); |
276 | info = add_packet(vis_packet, vis_info_len, &is_new); | 242 | info = add_packet(vis_packet, vis_info_len, &is_new); |
@@ -279,7 +245,7 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len) | |||
279 | 245 | ||
280 | /* only if we are server ourselves and packet is newer than the one in | 246 | /* only if we are server ourselves and packet is newer than the one in |
281 | * hash.*/ | 247 | * hash.*/ |
282 | if (is_vis_server_locked() && is_new) { | 248 | if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) { |
283 | memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); | 249 | memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); |
284 | if (list_empty(&info->send_list)) | 250 | if (list_empty(&info->send_list)) |
285 | list_add_tail(&info->send_list, &send_list); | 251 | list_add_tail(&info->send_list, &send_list); |
@@ -295,6 +261,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet, | |||
295 | struct vis_info *info; | 261 | struct vis_info *info; |
296 | int is_new; | 262 | int is_new; |
297 | unsigned long flags; | 263 | unsigned long flags; |
264 | int vis_server = atomic_read(&vis_mode); | ||
298 | 265 | ||
299 | /* clients shall not broadcast. */ | 266 | /* clients shall not broadcast. */ |
300 | if (is_bcast(vis_packet->target_orig)) | 267 | if (is_bcast(vis_packet->target_orig)) |
@@ -308,7 +275,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet, | |||
308 | 275 | ||
309 | 276 | ||
310 | /* send only if we're the target server or ... */ | 277 | /* send only if we're the target server or ... */ |
311 | if (is_vis_server_locked() && | 278 | if (vis_server == VIS_TYPE_SERVER_SYNC && |
312 | is_my_mac(info->packet.target_orig) && | 279 | is_my_mac(info->packet.target_orig) && |
313 | is_new) { | 280 | is_new) { |
314 | info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ | 281 | info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ |
@@ -372,6 +339,7 @@ static int generate_vis_packet(void) | |||
372 | unsigned long flags; | 339 | unsigned long flags; |
373 | 340 | ||
374 | info->first_seen = jiffies; | 341 | info->first_seen = jiffies; |
342 | info->packet.vis_type = atomic_read(&vis_mode); | ||
375 | 343 | ||
376 | spin_lock_irqsave(&orig_hash_lock, flags); | 344 | spin_lock_irqsave(&orig_hash_lock, flags); |
377 | memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); | 345 | memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); |
@@ -379,7 +347,7 @@ static int generate_vis_packet(void) | |||
379 | info->packet.seqno++; | 347 | info->packet.seqno++; |
380 | info->packet.entries = 0; | 348 | info->packet.entries = 0; |
381 | 349 | ||
382 | if (!is_vis_server_locked()) { | 350 | if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) { |
383 | best_tq = find_best_vis_server(info); | 351 | best_tq = find_best_vis_server(info); |
384 | if (best_tq < 0) { | 352 | if (best_tq < 0) { |
385 | spin_unlock_irqrestore(&orig_hash_lock, flags); | 353 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
@@ -577,7 +545,6 @@ int vis_init(void) | |||
577 | INIT_LIST_HEAD(&my_vis_info->send_list); | 545 | INIT_LIST_HEAD(&my_vis_info->send_list); |
578 | my_vis_info->packet.version = COMPAT_VERSION; | 546 | my_vis_info->packet.version = COMPAT_VERSION; |
579 | my_vis_info->packet.packet_type = BAT_VIS; | 547 | my_vis_info->packet.packet_type = BAT_VIS; |
580 | my_vis_info->packet.vis_type = VIS_TYPE_CLIENT_UPDATE; | ||
581 | my_vis_info->packet.ttl = TTL; | 548 | my_vis_info->packet.ttl = TTL; |
582 | my_vis_info->packet.seqno = 0; | 549 | my_vis_info->packet.seqno = 0; |
583 | my_vis_info->packet.entries = 0; | 550 | my_vis_info->packet.entries = 0; |
@@ -628,4 +595,3 @@ static void start_vis_timer(void) | |||
628 | queue_delayed_work(bat_event_workqueue, &vis_timer_wq, | 595 | queue_delayed_work(bat_event_workqueue, &vis_timer_wq, |
629 | (atomic_read(&vis_interval) * HZ) / 1000); | 596 | (atomic_read(&vis_interval) * HZ) / 1000); |
630 | } | 597 | } |
631 | |||
diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index 2e24258e69a4..0cdafde0ec3a 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h | |||
@@ -48,8 +48,6 @@ struct recvlist_node { | |||
48 | extern struct hashtable_t *vis_hash; | 48 | extern struct hashtable_t *vis_hash; |
49 | extern spinlock_t vis_hash_lock; | 49 | extern spinlock_t vis_hash_lock; |
50 | 50 | ||
51 | void vis_set_mode(int mode); | ||
52 | int is_vis_server(void); | ||
53 | void proc_vis_read_entry(struct seq_file *seq, | 51 | void proc_vis_read_entry(struct seq_file *seq, |
54 | struct vis_info_entry *entry, | 52 | struct vis_info_entry *entry, |
55 | struct hlist_head *if_list, | 53 | struct hlist_head *if_list, |