aboutsummaryrefslogtreecommitdiffstats
path: root/net/llc/llc_proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/llc/llc_proc.c')
-rw-r--r--net/llc/llc_proc.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c
index 6b3d033b3236..09dec6307206 100644
--- a/net/llc/llc_proc.c
+++ b/net/llc/llc_proc.c
@@ -34,17 +34,22 @@ static struct sock *llc_get_sk_idx(loff_t pos)
34{ 34{
35 struct list_head *sap_entry; 35 struct list_head *sap_entry;
36 struct llc_sap *sap; 36 struct llc_sap *sap;
37 struct hlist_nulls_node *node;
38 struct sock *sk = NULL; 37 struct sock *sk = NULL;
38 int i;
39 39
40 list_for_each(sap_entry, &llc_sap_list) { 40 list_for_each(sap_entry, &llc_sap_list) {
41 sap = list_entry(sap_entry, struct llc_sap, node); 41 sap = list_entry(sap_entry, struct llc_sap, node);
42 42
43 spin_lock_bh(&sap->sk_lock); 43 spin_lock_bh(&sap->sk_lock);
44 sk_nulls_for_each(sk, node, &sap->sk_list) { 44 for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) {
45 if (!pos) 45 struct hlist_nulls_head *head = &sap->sk_laddr_hash[i];
46 goto found; 46 struct hlist_nulls_node *node;
47 --pos; 47
48 sk_nulls_for_each(sk, node, head) {
49 if (!pos)
50 goto found; /* keep the lock */
51 --pos;
52 }
48 } 53 }
49 spin_unlock_bh(&sap->sk_lock); 54 spin_unlock_bh(&sap->sk_lock);
50 } 55 }
@@ -61,6 +66,19 @@ static void *llc_seq_start(struct seq_file *seq, loff_t *pos)
61 return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN; 66 return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN;
62} 67}
63 68
69static struct sock *laddr_hash_next(struct llc_sap *sap, int bucket)
70{
71 struct hlist_nulls_node *node;
72 struct sock *sk = NULL;
73
74 while (++bucket < LLC_SK_LADDR_HASH_ENTRIES)
75 sk_nulls_for_each(sk, node, &sap->sk_laddr_hash[bucket])
76 goto out;
77
78out:
79 return sk;
80}
81
64static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos) 82static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
65{ 83{
66 struct sock* sk, *next; 84 struct sock* sk, *next;
@@ -80,17 +98,15 @@ static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
80 } 98 }
81 llc = llc_sk(sk); 99 llc = llc_sk(sk);
82 sap = llc->sap; 100 sap = llc->sap;
101 sk = laddr_hash_next(sap, llc_sk_laddr_hashfn(sap, &llc->laddr));
102 if (sk)
103 goto out;
83 spin_unlock_bh(&sap->sk_lock); 104 spin_unlock_bh(&sap->sk_lock);
84 sk = NULL; 105 list_for_each_entry_continue(sap, &llc_sap_list, node) {
85 for (;;) {
86 if (sap->node.next == &llc_sap_list)
87 break;
88 sap = list_entry(sap->node.next, struct llc_sap, node);
89 spin_lock_bh(&sap->sk_lock); 106 spin_lock_bh(&sap->sk_lock);
90 if (!hlist_nulls_empty(&sap->sk_list)) { 107 sk = laddr_hash_next(sap, -1);
91 sk = sk_nulls_head(&sap->sk_list); 108 if (sk)
92 break; 109 break; /* keep the lock */
93 }
94 spin_unlock_bh(&sap->sk_lock); 110 spin_unlock_bh(&sap->sk_lock);
95 } 111 }
96out: 112out: