aboutsummaryrefslogtreecommitdiffstats
path: root/net/caif/caif_socket.c
diff options
context:
space:
mode:
authorsjur.brandeland@stericsson.com <sjur.brandeland@stericsson.com>2011-05-12 22:44:04 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-15 17:45:55 -0400
commitb3ccfbe4098a5542177d0f34e8979f32e7d606e1 (patch)
tree3f0046e3b519ea253db222abcb761af34b8a1718 /net/caif/caif_socket.c
parent43e3692101086add8719c3b8b50b05c9ac5b14e1 (diff)
caif: Protected in-flight packets using dev or sock refcont.
CAIF Socket Layer and ip-interface registers reference counters in CAIF service layer. The functions sock_hold, sock_put and dev_hold, dev_put are used by CAIF Stack to protect from freeing memory while packets are in-flight. Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/caif/caif_socket.c')
-rw-r--r--net/caif/caif_socket.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 20212424e2e8..01f612df7df1 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -209,6 +209,18 @@ static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt)
209 return 0; 209 return 0;
210} 210}
211 211
212static void cfsk_hold(struct cflayer *layr)
213{
214 struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
215 sock_hold(&cf_sk->sk);
216}
217
218static void cfsk_put(struct cflayer *layr)
219{
220 struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
221 sock_put(&cf_sk->sk);
222}
223
212/* Packet Control Callback function called from CAIF */ 224/* Packet Control Callback function called from CAIF */
213static void caif_ctrl_cb(struct cflayer *layr, 225static void caif_ctrl_cb(struct cflayer *layr,
214 enum caif_ctrlcmd flow, 226 enum caif_ctrlcmd flow,
@@ -232,6 +244,8 @@ static void caif_ctrl_cb(struct cflayer *layr,
232 244
233 case CAIF_CTRLCMD_INIT_RSP: 245 case CAIF_CTRLCMD_INIT_RSP:
234 /* We're now connected */ 246 /* We're now connected */
247 caif_client_register_refcnt(&cf_sk->layer,
248 cfsk_hold, cfsk_put);
235 dbfs_atomic_inc(&cnt.num_connect_resp); 249 dbfs_atomic_inc(&cnt.num_connect_resp);
236 cf_sk->sk.sk_state = CAIF_CONNECTED; 250 cf_sk->sk.sk_state = CAIF_CONNECTED;
237 set_tx_flow_on(cf_sk); 251 set_tx_flow_on(cf_sk);
@@ -242,7 +256,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
242 /* We're now disconnected */ 256 /* We're now disconnected */
243 cf_sk->sk.sk_state = CAIF_DISCONNECTED; 257 cf_sk->sk.sk_state = CAIF_DISCONNECTED;
244 cf_sk->sk.sk_state_change(&cf_sk->sk); 258 cf_sk->sk.sk_state_change(&cf_sk->sk);
245 cfcnfg_release_adap_layer(&cf_sk->layer);
246 break; 259 break;
247 260
248 case CAIF_CTRLCMD_INIT_FAIL_RSP: 261 case CAIF_CTRLCMD_INIT_FAIL_RSP:
@@ -837,8 +850,10 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
837 850
838 dbfs_atomic_inc(&cnt.num_connect_req); 851 dbfs_atomic_inc(&cnt.num_connect_req);
839 cf_sk->layer.receive = caif_sktrecv_cb; 852 cf_sk->layer.receive = caif_sktrecv_cb;
853
840 err = caif_connect_client(&cf_sk->conn_req, 854 err = caif_connect_client(&cf_sk->conn_req,
841 &cf_sk->layer, &ifindex, &headroom, &tailroom); 855 &cf_sk->layer, &ifindex, &headroom, &tailroom);
856
842 if (err < 0) { 857 if (err < 0) {
843 cf_sk->sk.sk_socket->state = SS_UNCONNECTED; 858 cf_sk->sk.sk_socket->state = SS_UNCONNECTED;
844 cf_sk->sk.sk_state = CAIF_DISCONNECTED; 859 cf_sk->sk.sk_state = CAIF_DISCONNECTED;
@@ -940,7 +955,6 @@ static int caif_release(struct socket *sock)
940 wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP); 955 wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP);
941 956
942 sock_orphan(sk); 957 sock_orphan(sk);
943 cf_sk->layer.dn = NULL;
944 sk_stream_kill_queues(&cf_sk->sk); 958 sk_stream_kill_queues(&cf_sk->sk);
945 release_sock(sk); 959 release_sock(sk);
946 sock_put(sk); 960 sock_put(sk);
@@ -1036,6 +1050,7 @@ static void caif_sock_destructor(struct sock *sk)
1036 } 1050 }
1037 sk_stream_kill_queues(&cf_sk->sk); 1051 sk_stream_kill_queues(&cf_sk->sk);
1038 dbfs_atomic_dec(&cnt.caif_nr_socks); 1052 dbfs_atomic_dec(&cnt.caif_nr_socks);
1053 caif_free_client(&cf_sk->layer);
1039} 1054}
1040 1055
1041static int caif_create(struct net *net, struct socket *sock, int protocol, 1056static int caif_create(struct net *net, struct socket *sock, int protocol,