aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/tcp_ipv4.c19
1 files changed, 5 insertions, 14 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 354721d67f69..3f5f7423b95c 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2045,10 +2045,7 @@ static void *established_get_first(struct seq_file *seq)
2045 struct hlist_node *node; 2045 struct hlist_node *node;
2046 struct inet_timewait_sock *tw; 2046 struct inet_timewait_sock *tw;
2047 2047
2048 /* We can reschedule _before_ having picked the target: */ 2048 read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2049 cond_resched_softirq();
2050
2051 read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
2052 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { 2049 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
2053 if (sk->sk_family != st->family) { 2050 if (sk->sk_family != st->family) {
2054 continue; 2051 continue;
@@ -2065,7 +2062,7 @@ static void *established_get_first(struct seq_file *seq)
2065 rc = tw; 2062 rc = tw;
2066 goto out; 2063 goto out;
2067 } 2064 }
2068 read_unlock(&tcp_hashinfo.ehash[st->bucket].lock); 2065 read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2069 st->state = TCP_SEQ_STATE_ESTABLISHED; 2066 st->state = TCP_SEQ_STATE_ESTABLISHED;
2070 } 2067 }
2071out: 2068out:
@@ -2092,14 +2089,11 @@ get_tw:
2092 cur = tw; 2089 cur = tw;
2093 goto out; 2090 goto out;
2094 } 2091 }
2095 read_unlock(&tcp_hashinfo.ehash[st->bucket].lock); 2092 read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2096 st->state = TCP_SEQ_STATE_ESTABLISHED; 2093 st->state = TCP_SEQ_STATE_ESTABLISHED;
2097 2094
2098 /* We can reschedule between buckets: */
2099 cond_resched_softirq();
2100
2101 if (++st->bucket < tcp_hashinfo.ehash_size) { 2095 if (++st->bucket < tcp_hashinfo.ehash_size) {
2102 read_lock(&tcp_hashinfo.ehash[st->bucket].lock); 2096 read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2103 sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain); 2097 sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
2104 } else { 2098 } else {
2105 cur = NULL; 2099 cur = NULL;
@@ -2144,7 +2138,6 @@ static void *tcp_get_idx(struct seq_file *seq, loff_t pos)
2144 2138
2145 if (!rc) { 2139 if (!rc) {
2146 inet_listen_unlock(&tcp_hashinfo); 2140 inet_listen_unlock(&tcp_hashinfo);
2147 local_bh_disable();
2148 st->state = TCP_SEQ_STATE_ESTABLISHED; 2141 st->state = TCP_SEQ_STATE_ESTABLISHED;
2149 rc = established_get_idx(seq, pos); 2142 rc = established_get_idx(seq, pos);
2150 } 2143 }
@@ -2177,7 +2170,6 @@ static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2177 rc = listening_get_next(seq, v); 2170 rc = listening_get_next(seq, v);
2178 if (!rc) { 2171 if (!rc) {
2179 inet_listen_unlock(&tcp_hashinfo); 2172 inet_listen_unlock(&tcp_hashinfo);
2180 local_bh_disable();
2181 st->state = TCP_SEQ_STATE_ESTABLISHED; 2173 st->state = TCP_SEQ_STATE_ESTABLISHED;
2182 rc = established_get_first(seq); 2174 rc = established_get_first(seq);
2183 } 2175 }
@@ -2209,8 +2201,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v)
2209 case TCP_SEQ_STATE_TIME_WAIT: 2201 case TCP_SEQ_STATE_TIME_WAIT:
2210 case TCP_SEQ_STATE_ESTABLISHED: 2202 case TCP_SEQ_STATE_ESTABLISHED:
2211 if (v) 2203 if (v)
2212 read_unlock(&tcp_hashinfo.ehash[st->bucket].lock); 2204 read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2213 local_bh_enable();
2214 break; 2205 break;
2215 } 2206 }
2216} 2207}