diff options
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 19 |
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 | } |
2071 | out: | 2068 | out: |
@@ -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 | } |