aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-12-14 19:54:12 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-12-18 14:07:56 -0500
commitbf4c63252490ba78fb833cc7acf1a5b1900c970f (patch)
tree628e5d6a2b0214a8d6d4c85ce61177a9fd59cbc5 /include
parent8192edef03f9b47f1cc1120724db525e63e218f3 (diff)
Bluetooth: convert conn hash to RCU
Handling hci_conn_hash with RCU make us avoid some locking and disable tasklets. Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'include')
-rw-r--r--include/net/bluetooth/hci_core.h45
1 files changed, 31 insertions, 14 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 14b200b08d84..e83243318924 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -392,7 +392,7 @@ static inline void hci_conn_hash_init(struct hci_dev *hdev)
392static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) 392static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
393{ 393{
394 struct hci_conn_hash *h = &hdev->conn_hash; 394 struct hci_conn_hash *h = &hdev->conn_hash;
395 list_add(&c->list, &h->list); 395 list_add_rcu(&c->list, &h->list);
396 switch (c->type) { 396 switch (c->type) {
397 case ACL_LINK: 397 case ACL_LINK:
398 h->acl_num++; 398 h->acl_num++;
@@ -410,7 +410,10 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
410static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) 410static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
411{ 411{
412 struct hci_conn_hash *h = &hdev->conn_hash; 412 struct hci_conn_hash *h = &hdev->conn_hash;
413 list_del(&c->list); 413
414 list_del_rcu(&c->list);
415 synchronize_rcu();
416
414 switch (c->type) { 417 switch (c->type) {
415 case ACL_LINK: 418 case ACL_LINK:
416 h->acl_num--; 419 h->acl_num--;
@@ -445,14 +448,18 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
445 __u16 handle) 448 __u16 handle)
446{ 449{
447 struct hci_conn_hash *h = &hdev->conn_hash; 450 struct hci_conn_hash *h = &hdev->conn_hash;
448 struct list_head *p;
449 struct hci_conn *c; 451 struct hci_conn *c;
450 452
451 list_for_each(p, &h->list) { 453 rcu_read_lock();
452 c = list_entry(p, struct hci_conn, list); 454
453 if (c->handle == handle) 455 list_for_each_entry_rcu(c, &h->list, list) {
456 if (c->handle == handle) {
457 rcu_read_unlock();
454 return c; 458 return c;
459 }
455 } 460 }
461 rcu_read_unlock();
462
456 return NULL; 463 return NULL;
457} 464}
458 465
@@ -460,14 +467,19 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
460 __u8 type, bdaddr_t *ba) 467 __u8 type, bdaddr_t *ba)
461{ 468{
462 struct hci_conn_hash *h = &hdev->conn_hash; 469 struct hci_conn_hash *h = &hdev->conn_hash;
463 struct list_head *p;
464 struct hci_conn *c; 470 struct hci_conn *c;
465 471
466 list_for_each(p, &h->list) { 472 rcu_read_lock();
467 c = list_entry(p, struct hci_conn, list); 473
468 if (c->type == type && !bacmp(&c->dst, ba)) 474 list_for_each_entry_rcu(c, &h->list, list) {
475 if (c->type == type && !bacmp(&c->dst, ba)) {
476 rcu_read_unlock();
469 return c; 477 return c;
478 }
470 } 479 }
480
481 rcu_read_unlock();
482
471 return NULL; 483 return NULL;
472} 484}
473 485
@@ -475,14 +487,19 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
475 __u8 type, __u16 state) 487 __u8 type, __u16 state)
476{ 488{
477 struct hci_conn_hash *h = &hdev->conn_hash; 489 struct hci_conn_hash *h = &hdev->conn_hash;
478 struct list_head *p;
479 struct hci_conn *c; 490 struct hci_conn *c;
480 491
481 list_for_each(p, &h->list) { 492 rcu_read_lock();
482 c = list_entry(p, struct hci_conn, list); 493
483 if (c->type == type && c->state == state) 494 list_for_each_entry_rcu(c, &h->list, list) {
495 if (c->type == type && c->state == state) {
496 rcu_read_unlock();
484 return c; 497 return c;
498 }
485 } 499 }
500
501 rcu_read_unlock();
502
486 return NULL; 503 return NULL;
487} 504}
488 505