pvcalls-front.c (5842c83596fcfa742978ec2840440ab56c7fdf79) | pvcalls-front.c (235a71c5390316429e2c7823119c5ea439816beb) |
---|---|
1/* 2 * (c) 2017 Stefano Stabellini <stefano@aporeto.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * --- 185 unchanged lines hidden (view full) --- 194 wake_up(&bedata->inflight_req); 195 pvcalls_exit(); 196 return IRQ_HANDLED; 197} 198 199static void pvcalls_front_free_map(struct pvcalls_bedata *bedata, 200 struct sock_mapping *map) 201{ | 1/* 2 * (c) 2017 Stefano Stabellini <stefano@aporeto.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * --- 185 unchanged lines hidden (view full) --- 194 wake_up(&bedata->inflight_req); 195 pvcalls_exit(); 196 return IRQ_HANDLED; 197} 198 199static void pvcalls_front_free_map(struct pvcalls_bedata *bedata, 200 struct sock_mapping *map) 201{ |
202 int i; 203 204 unbind_from_irqhandler(map->active.irq, map); 205 206 spin_lock(&bedata->socket_lock); 207 if (!list_empty(&map->list)) 208 list_del_init(&map->list); 209 spin_unlock(&bedata->socket_lock); 210 211 for (i = 0; i < (1 << PVCALLS_RING_ORDER); i++) 212 gnttab_end_foreign_access(map->active.ring->ref[i], 0, 0); 213 gnttab_end_foreign_access(map->active.ref, 0, 0); 214 free_page((unsigned long)map->active.ring); 215 216 kfree(map); |
|
202} 203 204static irqreturn_t pvcalls_front_conn_handler(int irq, void *sock_map) 205{ 206 struct sock_mapping *map = sock_map; 207 208 if (map == NULL) 209 return IRQ_HANDLED; --- 757 unchanged lines hidden (view full) --- 967 if (map->active_socket) 968 ret = pvcalls_front_poll_active(file, bedata, map, wait); 969 else 970 ret = pvcalls_front_poll_passive(file, bedata, map, wait); 971 pvcalls_exit(); 972 return ret; 973} 974 | 217} 218 219static irqreturn_t pvcalls_front_conn_handler(int irq, void *sock_map) 220{ 221 struct sock_mapping *map = sock_map; 222 223 if (map == NULL) 224 return IRQ_HANDLED; --- 757 unchanged lines hidden (view full) --- 982 if (map->active_socket) 983 ret = pvcalls_front_poll_active(file, bedata, map, wait); 984 else 985 ret = pvcalls_front_poll_passive(file, bedata, map, wait); 986 pvcalls_exit(); 987 return ret; 988} 989 |
990int pvcalls_front_release(struct socket *sock) 991{ 992 struct pvcalls_bedata *bedata; 993 struct sock_mapping *map; 994 int req_id, notify, ret; 995 struct xen_pvcalls_request *req; 996 997 if (sock->sk == NULL) 998 return 0; 999 1000 pvcalls_enter(); 1001 if (!pvcalls_front_dev) { 1002 pvcalls_exit(); 1003 return -EIO; 1004 } 1005 1006 bedata = dev_get_drvdata(&pvcalls_front_dev->dev); 1007 1008 map = (struct sock_mapping *) sock->sk->sk_send_head; 1009 if (map == NULL) { 1010 pvcalls_exit(); 1011 return 0; 1012 } 1013 1014 spin_lock(&bedata->socket_lock); 1015 ret = get_request(bedata, &req_id); 1016 if (ret < 0) { 1017 spin_unlock(&bedata->socket_lock); 1018 pvcalls_exit(); 1019 return ret; 1020 } 1021 sock->sk->sk_send_head = NULL; 1022 1023 req = RING_GET_REQUEST(&bedata->ring, req_id); 1024 req->req_id = req_id; 1025 req->cmd = PVCALLS_RELEASE; 1026 req->u.release.id = (uintptr_t)map; 1027 1028 bedata->ring.req_prod_pvt++; 1029 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&bedata->ring, notify); 1030 spin_unlock(&bedata->socket_lock); 1031 if (notify) 1032 notify_remote_via_irq(bedata->irq); 1033 1034 wait_event(bedata->inflight_req, 1035 READ_ONCE(bedata->rsp[req_id].req_id) == req_id); 1036 1037 if (map->active_socket) { 1038 /* 1039 * Set in_error and wake up inflight_conn_req to force 1040 * recvmsg waiters to exit. 1041 */ 1042 map->active.ring->in_error = -EBADF; 1043 wake_up_interruptible(&map->active.inflight_conn_req); 1044 1045 /* 1046 * Wait until there are no more waiters on the mutexes. 1047 * We know that no new waiters can be added because sk_send_head 1048 * is set to NULL -- we only need to wait for the existing 1049 * waiters to return. 1050 */ 1051 while (!mutex_trylock(&map->active.in_mutex) || 1052 !mutex_trylock(&map->active.out_mutex)) 1053 cpu_relax(); 1054 1055 pvcalls_front_free_map(bedata, map); 1056 } else { 1057 spin_lock(&bedata->socket_lock); 1058 list_del(&map->list); 1059 spin_unlock(&bedata->socket_lock); 1060 if (READ_ONCE(map->passive.inflight_req_id) != 1061 PVCALLS_INVALID_ID) { 1062 pvcalls_front_free_map(bedata, 1063 map->passive.accept_map); 1064 } 1065 kfree(map); 1066 } 1067 WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID); 1068 1069 pvcalls_exit(); 1070 return 0; 1071} 1072 |
|
975static const struct xenbus_device_id pvcalls_front_ids[] = { 976 { "pvcalls" }, 977 { "" } 978}; 979 980static int pvcalls_front_remove(struct xenbus_device *dev) 981{ 982 struct pvcalls_bedata *bedata; --- 197 unchanged lines hidden --- | 1073static const struct xenbus_device_id pvcalls_front_ids[] = { 1074 { "pvcalls" }, 1075 { "" } 1076}; 1077 1078static int pvcalls_front_remove(struct xenbus_device *dev) 1079{ 1080 struct pvcalls_bedata *bedata; --- 197 unchanged lines hidden --- |