diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 482c2aab3d67e6dcdf2a6db9fbf2b6a0a4eeed57..a17701740624f5a512ff21b39b6dda648443aa9f 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1185,9 +1185,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest, int flags); int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, __u8 use_as_src, gfp_t gfp); -int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *, - void fastcall (*rcu_call)(struct rcu_head *, - void (*func)(struct rcu_head *))); +int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, struct sctp_sock *); union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp, diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index dfffa94fb9f636366616ca3e349ffcfee746f5cb..cae95af9a8cc147f2652c7b2a3c6c80880fd0f7a 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -180,9 +180,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, /* Delete an address from the bind address list in the SCTP_bind_addr * structure. */ -int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr, - void fastcall (*rcu_call)(struct rcu_head *head, - void (*func)(struct rcu_head *head))) +int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) { struct sctp_sockaddr_entry *addr, *temp; @@ -198,15 +196,10 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr, } } - /* Call the rcu callback provided in the args. This function is - * called by both BH packet processing and user side socket option - * processing, but it works on different lists in those 2 contexts. - * Each context provides it's own callback, whether call_rcu_bh() - * or call_rcu(), to make sure that we wait for an appropriate time. - */ if (addr && !addr->valid) { - rcu_call(&addr->rcu, sctp_local_addr_free); + call_rcu(&addr->rcu, sctp_local_addr_free); SCTP_DBG_OBJCNT_DEC(addr); + return 0; } return -EINVAL; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 5de4729fe9939a7b3b6d82f2aa8bdb2533bcf493..c60564dd169d4c2c37f588c079a518626bbbeeec 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -2953,13 +2953,17 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, /* This is always done in BH context with a socket lock * held, so the list can not change. */ + local_bh_disable(); list_for_each_entry(saddr, &bp->address_list, list) { if (sctp_cmp_addr_exact(&saddr->a, &addr)) saddr->use_as_src = 1; } + local_bh_enable(); break; case SCTP_PARAM_DEL_IP: - retval = sctp_del_bind_addr(bp, &addr, call_rcu_bh); + local_bh_disable(); + retval = sctp_del_bind_addr(bp, &addr); + local_bh_enable(); list_for_each(pos, &asoc->peer.transport_addr_list) { transport = list_entry(pos, struct sctp_transport, transports); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a7ecf3159e53b0e759e6e8d674699f28617628d0..6ce9b490fad578fb1841acd9d9a02b37f7ddf47c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -660,7 +660,7 @@ static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt) * socket routing and failover schemes. Refer to comments in * sctp_do_bind(). -daisy */ - retval = sctp_del_bind_addr(bp, sa_addr, call_rcu); + retval = sctp_del_bind_addr(bp, sa_addr); addr_buf += af->sockaddr_len; err_bindx_rem: