aboutsummaryrefslogtreecommitdiffstats
path: root/net/caif/caif_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/caif/caif_socket.c')
-rw-r--r--net/caif/caif_socket.c106
1 files changed, 52 insertions, 54 deletions
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 37a4034dfc29..b840395ced1d 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -48,6 +48,7 @@ static struct dentry *debugfsdir;
48#ifdef CONFIG_DEBUG_FS 48#ifdef CONFIG_DEBUG_FS
49struct debug_fs_counter { 49struct debug_fs_counter {
50 atomic_t caif_nr_socks; 50 atomic_t caif_nr_socks;
51 atomic_t caif_sock_create;
51 atomic_t num_connect_req; 52 atomic_t num_connect_req;
52 atomic_t num_connect_resp; 53 atomic_t num_connect_resp;
53 atomic_t num_connect_fail_resp; 54 atomic_t num_connect_fail_resp;
@@ -59,11 +60,11 @@ struct debug_fs_counter {
59 atomic_t num_rx_flow_on; 60 atomic_t num_rx_flow_on;
60}; 61};
61static struct debug_fs_counter cnt; 62static struct debug_fs_counter cnt;
62#define dbfs_atomic_inc(v) atomic_inc(v) 63#define dbfs_atomic_inc(v) atomic_inc_return(v)
63#define dbfs_atomic_dec(v) atomic_dec(v) 64#define dbfs_atomic_dec(v) atomic_dec_return(v)
64#else 65#else
65#define dbfs_atomic_inc(v) 66#define dbfs_atomic_inc(v) 0
66#define dbfs_atomic_dec(v) 67#define dbfs_atomic_dec(v) 0
67#endif 68#endif
68 69
69struct caifsock { 70struct caifsock {
@@ -155,9 +156,10 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
155 156
156 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= 157 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
157 (unsigned)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) { 158 (unsigned)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) {
158 pr_debug("sending flow OFF (queue len = %d %d)\n", 159 if (net_ratelimit())
159 atomic_read(&cf_sk->sk.sk_rmem_alloc), 160 pr_debug("sending flow OFF (queue len = %d %d)\n",
160 sk_rcvbuf_lowwater(cf_sk)); 161 atomic_read(&cf_sk->sk.sk_rmem_alloc),
162 sk_rcvbuf_lowwater(cf_sk));
161 set_rx_flow_off(cf_sk); 163 set_rx_flow_off(cf_sk);
162 dbfs_atomic_inc(&cnt.num_rx_flow_off); 164 dbfs_atomic_inc(&cnt.num_rx_flow_off);
163 caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); 165 caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
@@ -168,7 +170,8 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
168 return err; 170 return err;
169 if (!sk_rmem_schedule(sk, skb->truesize) && rx_flow_is_on(cf_sk)) { 171 if (!sk_rmem_schedule(sk, skb->truesize) && rx_flow_is_on(cf_sk)) {
170 set_rx_flow_off(cf_sk); 172 set_rx_flow_off(cf_sk);
171 pr_debug("sending flow OFF due to rmem_schedule\n"); 173 if (net_ratelimit())
174 pr_debug("sending flow OFF due to rmem_schedule\n");
172 dbfs_atomic_inc(&cnt.num_rx_flow_off); 175 dbfs_atomic_inc(&cnt.num_rx_flow_off);
173 caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); 176 caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
174 } 177 }
@@ -202,13 +205,25 @@ static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt)
202 skb = cfpkt_tonative(pkt); 205 skb = cfpkt_tonative(pkt);
203 206
204 if (unlikely(cf_sk->sk.sk_state != CAIF_CONNECTED)) { 207 if (unlikely(cf_sk->sk.sk_state != CAIF_CONNECTED)) {
205 cfpkt_destroy(pkt); 208 kfree_skb(skb);
206 return 0; 209 return 0;
207 } 210 }
208 caif_queue_rcv_skb(&cf_sk->sk, skb); 211 caif_queue_rcv_skb(&cf_sk->sk, skb);
209 return 0; 212 return 0;
210} 213}
211 214
215static void cfsk_hold(struct cflayer *layr)
216{
217 struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
218 sock_hold(&cf_sk->sk);
219}
220
221static void cfsk_put(struct cflayer *layr)
222{
223 struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
224 sock_put(&cf_sk->sk);
225}
226
212/* Packet Control Callback function called from CAIF */ 227/* Packet Control Callback function called from CAIF */
213static void caif_ctrl_cb(struct cflayer *layr, 228static void caif_ctrl_cb(struct cflayer *layr,
214 enum caif_ctrlcmd flow, 229 enum caif_ctrlcmd flow,
@@ -232,6 +247,8 @@ static void caif_ctrl_cb(struct cflayer *layr,
232 247
233 case CAIF_CTRLCMD_INIT_RSP: 248 case CAIF_CTRLCMD_INIT_RSP:
234 /* We're now connected */ 249 /* We're now connected */
250 caif_client_register_refcnt(&cf_sk->layer,
251 cfsk_hold, cfsk_put);
235 dbfs_atomic_inc(&cnt.num_connect_resp); 252 dbfs_atomic_inc(&cnt.num_connect_resp);
236 cf_sk->sk.sk_state = CAIF_CONNECTED; 253 cf_sk->sk.sk_state = CAIF_CONNECTED;
237 set_tx_flow_on(cf_sk); 254 set_tx_flow_on(cf_sk);
@@ -242,7 +259,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
242 /* We're now disconnected */ 259 /* We're now disconnected */
243 cf_sk->sk.sk_state = CAIF_DISCONNECTED; 260 cf_sk->sk.sk_state = CAIF_DISCONNECTED;
244 cf_sk->sk.sk_state_change(&cf_sk->sk); 261 cf_sk->sk.sk_state_change(&cf_sk->sk);
245 cfcnfg_release_adap_layer(&cf_sk->layer);
246 break; 262 break;
247 263
248 case CAIF_CTRLCMD_INIT_FAIL_RSP: 264 case CAIF_CTRLCMD_INIT_FAIL_RSP:
@@ -519,43 +535,14 @@ static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk,
519 int noblock, long timeo) 535 int noblock, long timeo)
520{ 536{
521 struct cfpkt *pkt; 537 struct cfpkt *pkt;
522 int ret, loopcnt = 0;
523 538
524 pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb); 539 pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb);
525 memset(cfpkt_info(pkt), 0, sizeof(struct caif_payload_info)); 540 memset(skb->cb, 0, sizeof(struct caif_payload_info));
526 do {
527 541
528 ret = -ETIMEDOUT; 542 if (cf_sk->layer.dn == NULL)
543 return -EINVAL;
529 544
530 /* Slight paranoia, probably not needed. */ 545 return cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
531 if (unlikely(loopcnt++ > 1000)) {
532 pr_warn("transmit retries failed, error = %d\n", ret);
533 break;
534 }
535
536 if (cf_sk->layer.dn != NULL)
537 ret = cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
538 if (likely(ret >= 0))
539 break;
540 /* if transmit return -EAGAIN, then retry */
541 if (noblock && ret == -EAGAIN)
542 break;
543 timeo = caif_wait_for_flow_on(cf_sk, 0, timeo, &ret);
544 if (signal_pending(current)) {
545 ret = sock_intr_errno(timeo);
546 break;
547 }
548 if (ret)
549 break;
550 if (cf_sk->sk.sk_state != CAIF_CONNECTED ||
551 sock_flag(&cf_sk->sk, SOCK_DEAD) ||
552 (cf_sk->sk.sk_shutdown & RCV_SHUTDOWN)) {
553 ret = -EPIPE;
554 cf_sk->sk.sk_err = EPIPE;
555 break;
556 }
557 } while (ret == -EAGAIN);
558 return ret;
559} 546}
560 547
561/* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */ 548/* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */
@@ -620,7 +607,9 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock,
620 goto err; 607 goto err;
621 ret = transmit_skb(skb, cf_sk, noblock, timeo); 608 ret = transmit_skb(skb, cf_sk, noblock, timeo);
622 if (ret < 0) 609 if (ret < 0)
623 goto err; 610 /* skb is already freed */
611 return ret;
612
624 return len; 613 return len;
625err: 614err:
626 kfree_skb(skb); 615 kfree_skb(skb);
@@ -826,7 +815,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
826 sk->sk_state == CAIF_DISCONNECTED); 815 sk->sk_state == CAIF_DISCONNECTED);
827 if (sk->sk_shutdown & SHUTDOWN_MASK) { 816 if (sk->sk_shutdown & SHUTDOWN_MASK) {
828 /* Allow re-connect after SHUTDOWN_IND */ 817 /* Allow re-connect after SHUTDOWN_IND */
829 caif_disconnect_client(&cf_sk->layer); 818 caif_disconnect_client(sock_net(sk), &cf_sk->layer);
830 break; 819 break;
831 } 820 }
832 /* No reconnect on a seqpacket socket */ 821 /* No reconnect on a seqpacket socket */
@@ -852,7 +841,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
852 sock->state = SS_CONNECTING; 841 sock->state = SS_CONNECTING;
853 sk->sk_state = CAIF_CONNECTING; 842 sk->sk_state = CAIF_CONNECTING;
854 843
855 /* Check priority value coming from socket */ 844 /* Check priority value comming from socket */
856 /* if priority value is out of range it will be ajusted */ 845 /* if priority value is out of range it will be ajusted */
857 if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX) 846 if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX)
858 cf_sk->conn_req.priority = CAIF_PRIO_MAX; 847 cf_sk->conn_req.priority = CAIF_PRIO_MAX;
@@ -866,8 +855,10 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
866 855
867 dbfs_atomic_inc(&cnt.num_connect_req); 856 dbfs_atomic_inc(&cnt.num_connect_req);
868 cf_sk->layer.receive = caif_sktrecv_cb; 857 cf_sk->layer.receive = caif_sktrecv_cb;
869 err = caif_connect_client(&cf_sk->conn_req, 858
859 err = caif_connect_client(sock_net(sk), &cf_sk->conn_req,
870 &cf_sk->layer, &ifindex, &headroom, &tailroom); 860 &cf_sk->layer, &ifindex, &headroom, &tailroom);
861
871 if (err < 0) { 862 if (err < 0) {
872 cf_sk->sk.sk_socket->state = SS_UNCONNECTED; 863 cf_sk->sk.sk_socket->state = SS_UNCONNECTED;
873 cf_sk->sk.sk_state = CAIF_DISCONNECTED; 864 cf_sk->sk.sk_state = CAIF_DISCONNECTED;
@@ -947,13 +938,14 @@ static int caif_release(struct socket *sock)
947 * caif_queue_rcv_skb checks SOCK_DEAD holding the queue lock, 938 * caif_queue_rcv_skb checks SOCK_DEAD holding the queue lock,
948 * this ensures no packets when sock is dead. 939 * this ensures no packets when sock is dead.
949 */ 940 */
950 spin_lock(&sk->sk_receive_queue.lock); 941 spin_lock_bh(&sk->sk_receive_queue.lock);
951 sock_set_flag(sk, SOCK_DEAD); 942 sock_set_flag(sk, SOCK_DEAD);
952 spin_unlock(&sk->sk_receive_queue.lock); 943 spin_unlock_bh(&sk->sk_receive_queue.lock);
953 sock->sk = NULL; 944 sock->sk = NULL;
954 945
955 dbfs_atomic_inc(&cnt.num_disconnect); 946 dbfs_atomic_inc(&cnt.num_disconnect);
956 947
948 WARN_ON(IS_ERR(cf_sk->debugfs_socket_dir));
957 if (cf_sk->debugfs_socket_dir != NULL) 949 if (cf_sk->debugfs_socket_dir != NULL)
958 debugfs_remove_recursive(cf_sk->debugfs_socket_dir); 950 debugfs_remove_recursive(cf_sk->debugfs_socket_dir);
959 951
@@ -963,13 +955,12 @@ static int caif_release(struct socket *sock)
963 955
964 if (cf_sk->sk.sk_socket->state == SS_CONNECTED || 956 if (cf_sk->sk.sk_socket->state == SS_CONNECTED ||
965 cf_sk->sk.sk_socket->state == SS_CONNECTING) 957 cf_sk->sk.sk_socket->state == SS_CONNECTING)
966 res = caif_disconnect_client(&cf_sk->layer); 958 res = caif_disconnect_client(sock_net(sk), &cf_sk->layer);
967 959
968 cf_sk->sk.sk_socket->state = SS_DISCONNECTING; 960 cf_sk->sk.sk_socket->state = SS_DISCONNECTING;
969 wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP); 961 wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP);
970 962
971 sock_orphan(sk); 963 sock_orphan(sk);
972 cf_sk->layer.dn = NULL;
973 sk_stream_kill_queues(&cf_sk->sk); 964 sk_stream_kill_queues(&cf_sk->sk);
974 release_sock(sk); 965 release_sock(sk);
975 sock_put(sk); 966 sock_put(sk);
@@ -1060,16 +1051,18 @@ static void caif_sock_destructor(struct sock *sk)
1060 caif_assert(sk_unhashed(sk)); 1051 caif_assert(sk_unhashed(sk));
1061 caif_assert(!sk->sk_socket); 1052 caif_assert(!sk->sk_socket);
1062 if (!sock_flag(sk, SOCK_DEAD)) { 1053 if (!sock_flag(sk, SOCK_DEAD)) {
1063 pr_info("Attempt to release alive CAIF socket: %p\n", sk); 1054 pr_debug("Attempt to release alive CAIF socket: %p\n", sk);
1064 return; 1055 return;
1065 } 1056 }
1066 sk_stream_kill_queues(&cf_sk->sk); 1057 sk_stream_kill_queues(&cf_sk->sk);
1067 dbfs_atomic_dec(&cnt.caif_nr_socks); 1058 dbfs_atomic_dec(&cnt.caif_nr_socks);
1059 caif_free_client(&cf_sk->layer);
1068} 1060}
1069 1061
1070static int caif_create(struct net *net, struct socket *sock, int protocol, 1062static int caif_create(struct net *net, struct socket *sock, int protocol,
1071 int kern) 1063 int kern)
1072{ 1064{
1065 int num;
1073 struct sock *sk = NULL; 1066 struct sock *sk = NULL;
1074 struct caifsock *cf_sk = NULL; 1067 struct caifsock *cf_sk = NULL;
1075 static struct proto prot = {.name = "PF_CAIF", 1068 static struct proto prot = {.name = "PF_CAIF",
@@ -1132,14 +1125,16 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
1132 cf_sk->conn_req.protocol = protocol; 1125 cf_sk->conn_req.protocol = protocol;
1133 /* Increase the number of sockets created. */ 1126 /* Increase the number of sockets created. */
1134 dbfs_atomic_inc(&cnt.caif_nr_socks); 1127 dbfs_atomic_inc(&cnt.caif_nr_socks);
1128 num = dbfs_atomic_inc(&cnt.caif_sock_create);
1135#ifdef CONFIG_DEBUG_FS 1129#ifdef CONFIG_DEBUG_FS
1136 if (!IS_ERR(debugfsdir)) { 1130 if (!IS_ERR(debugfsdir)) {
1131
1137 /* Fill in some information concerning the misc socket. */ 1132 /* Fill in some information concerning the misc socket. */
1138 snprintf(cf_sk->name, sizeof(cf_sk->name), "cfsk%d", 1133 snprintf(cf_sk->name, sizeof(cf_sk->name), "cfsk%d", num);
1139 atomic_read(&cnt.caif_nr_socks));
1140 1134
1141 cf_sk->debugfs_socket_dir = 1135 cf_sk->debugfs_socket_dir =
1142 debugfs_create_dir(cf_sk->name, debugfsdir); 1136 debugfs_create_dir(cf_sk->name, debugfsdir);
1137
1143 debugfs_create_u32("sk_state", S_IRUSR | S_IWUSR, 1138 debugfs_create_u32("sk_state", S_IRUSR | S_IWUSR,
1144 cf_sk->debugfs_socket_dir, 1139 cf_sk->debugfs_socket_dir,
1145 (u32 *) &cf_sk->sk.sk_state); 1140 (u32 *) &cf_sk->sk.sk_state);
@@ -1183,6 +1178,9 @@ static int __init caif_sktinit_module(void)
1183 debugfs_create_u32("num_sockets", S_IRUSR | S_IWUSR, 1178 debugfs_create_u32("num_sockets", S_IRUSR | S_IWUSR,
1184 debugfsdir, 1179 debugfsdir,
1185 (u32 *) &cnt.caif_nr_socks); 1180 (u32 *) &cnt.caif_nr_socks);
1181 debugfs_create_u32("num_create", S_IRUSR | S_IWUSR,
1182 debugfsdir,
1183 (u32 *) &cnt.caif_sock_create);
1186 debugfs_create_u32("num_connect_req", S_IRUSR | S_IWUSR, 1184 debugfs_create_u32("num_connect_req", S_IRUSR | S_IWUSR,
1187 debugfsdir, 1185 debugfsdir,
1188 (u32 *) &cnt.num_connect_req); 1186 (u32 *) &cnt.num_connect_req);