aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/transport.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2012-12-06 04:25:05 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-07 14:15:04 -0500
commit45122ca26ced7fae41049326a3797a73f961db2e (patch)
tree347843ccf9b6a9eb9a4507e07b4c19faf0e59f70 /net/sctp/transport.c
parent0b0fe913bf6d551642eb8892ed90be7358906379 (diff)
sctp: Add RCU protection to assoc->transport_addr_list
peer.transport_addr_list is currently only protected by sk_sock which is inpractical to acquire for procfs dumping purposes. This patch adds RCU protection allowing for the procfs readers to enter RCU read-side critical sections. Modification of the list continues to be serialized via sk_lock. V2: Use list_del_rcu() in sctp_association_free() to be safe Skip transports marked dead when dumping for procfs Cc: Vlad Yasevich <vyasevich@gmail.com> Cc: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: Thomas Graf <tgraf@suug.ch> Acked-by: Vlad Yasevich <vyasevich@gmail.com> Acked-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/transport.c')
-rw-r--r--net/sctp/transport.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 310f11eb2206..4e45bb68aef0 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -163,13 +163,11 @@ void sctp_transport_free(struct sctp_transport *transport)
163 sctp_transport_put(transport); 163 sctp_transport_put(transport);
164} 164}
165 165
166/* Destroy the transport data structure. 166static void sctp_transport_destroy_rcu(struct rcu_head *head)
167 * Assumes there are no more users of this structure.
168 */
169static void sctp_transport_destroy(struct sctp_transport *transport)
170{ 167{
171 SCTP_ASSERT(transport->dead, "Transport is not dead", return); 168 struct sctp_transport *transport;
172 169
170 transport = container_of(head, struct sctp_transport, rcu);
173 if (transport->asoc) 171 if (transport->asoc)
174 sctp_association_put(transport->asoc); 172 sctp_association_put(transport->asoc);
175 173
@@ -180,6 +178,16 @@ static void sctp_transport_destroy(struct sctp_transport *transport)
180 SCTP_DBG_OBJCNT_DEC(transport); 178 SCTP_DBG_OBJCNT_DEC(transport);
181} 179}
182 180
181/* Destroy the transport data structure.
182 * Assumes there are no more users of this structure.
183 */
184static void sctp_transport_destroy(struct sctp_transport *transport)
185{
186 SCTP_ASSERT(transport->dead, "Transport is not dead", return);
187
188 call_rcu(&transport->rcu, sctp_transport_destroy_rcu);
189}
190
183/* Start T3_rtx timer if it is not already running and update the heartbeat 191/* Start T3_rtx timer if it is not already running and update the heartbeat
184 * timer. This routine is called every time a DATA chunk is sent. 192 * timer. This routine is called every time a DATA chunk is sent.
185 */ 193 */