aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Luessing <linus.luessing@web.de>2010-02-19 10:18:08 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-03 19:43:02 -0500
commit837b8248f6206a6b08b3d6defe2946282e432679 (patch)
treecb17aef52d0578dea091365c26656712abd8b087 /drivers
parentbc0ad071a788625abb23aee4cb3c07d17d501641 (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.c2
-rw-r--r--drivers/staging/batman-adv/main.h1
-rw-r--r--drivers/staging/batman-adv/proc.c15
-rw-r--r--drivers/staging/batman-adv/send.c3
-rw-r--r--drivers/staging/batman-adv/vis.c46
-rw-r--r--drivers/staging/batman-adv/vis.h2
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
44atomic_t originator_interval; 44atomic_t originator_interval;
45atomic_t vis_interval; 45atomic_t vis_interval;
46atomic_t vis_mode;
46atomic_t aggregation_enabled; 47atomic_t aggregation_enabled;
47int16_t num_hna; 48int16_t num_hna;
48int16_t num_ifs; 49int16_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
131extern atomic_t originator_interval; 131extern atomic_t originator_interval;
132extern atomic_t vis_interval; 132extern atomic_t vis_interval;
133extern atomic_t vis_mode;
133extern atomic_t aggregation_enabled; 134extern atomic_t aggregation_enabled;
134extern int16_t num_hna; 135extern int16_t num_hna;
135extern int16_t num_ifs; 136extern 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
354static int proc_vis_srv_read(struct seq_file *seq, void *offset) 354static 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 */
52void 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 */
64static 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 */
74int 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 */
87static int vis_info_cmp(void *data1, void *data2) 52static 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 {
48extern struct hashtable_t *vis_hash; 48extern struct hashtable_t *vis_hash;
49extern spinlock_t vis_hash_lock; 49extern spinlock_t vis_hash_lock;
50 50
51void vis_set_mode(int mode);
52int is_vis_server(void);
53void proc_vis_read_entry(struct seq_file *seq, 51void 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,