* [PATCH 0/2] pvcalls-front improvements
@ 2018-02-05 22:51 Stefano Stabellini
2018-02-05 22:51 ` [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount Stefano Stabellini
0 siblings, 1 reply; 7+ messages in thread
From: Stefano Stabellini @ 2018-02-05 22:51 UTC (permalink / raw)
To: boris.ostrovsky, jgross; +Cc: sstabellini, xen-devel, linux-kernel
Hi all,
this small series introduces a per socket refcount to increase the
efficiency on socket release operations, and makes releasing passive
sockets safe.
Cheers,
Stefano
Stefano Stabellini (2):
pvcalls-front: introduce a per sock_mapping refcount
pvcalls-front: wait for other operations to return when release passive sockets
drivers/xen/pvcalls-front.c | 196 +++++++++++++++++++-------------------------
1 file changed, 84 insertions(+), 112 deletions(-)
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount 2018-02-05 22:51 [PATCH 0/2] pvcalls-front improvements Stefano Stabellini @ 2018-02-05 22:51 ` Stefano Stabellini 2018-02-05 22:51 ` [PATCH 2/2] pvcalls-front: wait for other operations to return when release passive sockets Stefano Stabellini 2018-02-12 13:14 ` [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount Juergen Gross 0 siblings, 2 replies; 7+ messages in thread From: Stefano Stabellini @ 2018-02-05 22:51 UTC (permalink / raw) To: boris.ostrovsky, jgross Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini Introduce a per sock_mapping refcount, in addition to the existing global refcount. Thanks to the sock_mapping refcount, we can safely wait for it to be 1 in pvcalls_front_release before freeing an active socket, instead of waiting for the global refcount to be 1. Signed-off-by: Stefano Stabellini <stefano@aporeto.com> --- drivers/xen/pvcalls-front.c | 190 ++++++++++++++++++-------------------------- 1 file changed, 78 insertions(+), 112 deletions(-) diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c index 4c789e6..164d3ad 100644 --- a/drivers/xen/pvcalls-front.c +++ b/drivers/xen/pvcalls-front.c @@ -60,6 +60,7 @@ struct sock_mapping { bool active_socket; struct list_head list; struct socket *sock; + atomic_t refcount; union { struct { int irq; @@ -93,6 +94,33 @@ struct sock_mapping { }; }; +static inline struct sock_mapping *pvcalls_enter_sock(struct socket *sock) +{ + struct sock_mapping *map = NULL; + + if (!pvcalls_front_dev || &pvcalls_front_dev->dev == NULL) + return ERR_PTR(-ENOTCONN); + + pvcalls_enter(); + map = (struct sock_mapping *) sock->sk->sk_send_head; + if (map == NULL) { + pvcalls_exit() + return ERR_PTR(-ENOTSOCK); + } + + atomic_inc(&map->refcount); + return map; +} + +static inline void pvcalls_exit_sock(struct socket *sock) +{ + struct sock_mapping *map = NULL; + + map = (struct sock_mapping *) sock->sk->sk_send_head; + atomic_dec(&map->refcount); + pvcalls_exit(); +} + static inline int get_request(struct pvcalls_bedata *bedata, int *req_id) { *req_id = bedata->ring.req_prod_pvt & (RING_SIZE(&bedata->ring) - 1); @@ -369,31 +397,23 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr, if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) return -EOPNOTSUPP; - pvcalls_enter(); - if (!pvcalls_front_dev) { - pvcalls_exit(); - return -ENOTCONN; - } + map = pvcalls_enter_sock(sock); + if (IS_ERR(map)) + return PTR_ERR(map); bedata = dev_get_drvdata(&pvcalls_front_dev->dev); - map = (struct sock_mapping *)sock->sk->sk_send_head; - if (!map) { - pvcalls_exit(); - return -ENOTSOCK; - } - spin_lock(&bedata->socket_lock); ret = get_request(bedata, &req_id); if (ret < 0) { spin_unlock(&bedata->socket_lock); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } ret = create_active(map, &evtchn); if (ret < 0) { spin_unlock(&bedata->socket_lock); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } @@ -423,7 +443,7 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr, smp_rmb(); ret = bedata->rsp[req_id].ret; bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } @@ -488,23 +508,15 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, if (flags & (MSG_CONFIRM|MSG_DONTROUTE|MSG_EOR|MSG_OOB)) return -EOPNOTSUPP; - pvcalls_enter(); - if (!pvcalls_front_dev) { - pvcalls_exit(); - return -ENOTCONN; - } + map = pvcalls_enter_sock(sock); + if (IS_ERR(map)) + return PTR_ERR(map); bedata = dev_get_drvdata(&pvcalls_front_dev->dev); - map = (struct sock_mapping *) sock->sk->sk_send_head; - if (!map) { - pvcalls_exit(); - return -ENOTSOCK; - } - mutex_lock(&map->active.out_mutex); if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) { mutex_unlock(&map->active.out_mutex); - pvcalls_exit(); + pvcalls_exit_sock(sock); return -EAGAIN; } if (len > INT_MAX) @@ -526,7 +538,7 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, tot_sent = sent; mutex_unlock(&map->active.out_mutex); - pvcalls_exit(); + pvcalls_exit_sock(sock); return tot_sent; } @@ -591,19 +603,11 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, if (flags & (MSG_CMSG_CLOEXEC|MSG_ERRQUEUE|MSG_OOB|MSG_TRUNC)) return -EOPNOTSUPP; - pvcalls_enter(); - if (!pvcalls_front_dev) { - pvcalls_exit(); - return -ENOTCONN; - } + map = pvcalls_enter_sock(sock); + if (IS_ERR(map)) + return PTR_ERR(map); bedata = dev_get_drvdata(&pvcalls_front_dev->dev); - map = (struct sock_mapping *) sock->sk->sk_send_head; - if (!map) { - pvcalls_exit(); - return -ENOTSOCK; - } - mutex_lock(&map->active.in_mutex); if (len > XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER)) len = XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER); @@ -623,7 +627,7 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, ret = 0; mutex_unlock(&map->active.in_mutex); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } @@ -637,24 +641,16 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len) if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) return -EOPNOTSUPP; - pvcalls_enter(); - if (!pvcalls_front_dev) { - pvcalls_exit(); - return -ENOTCONN; - } + map = pvcalls_enter_sock(sock); + if (IS_ERR(map)) + return PTR_ERR(map); bedata = dev_get_drvdata(&pvcalls_front_dev->dev); - map = (struct sock_mapping *) sock->sk->sk_send_head; - if (map == NULL) { - pvcalls_exit(); - return -ENOTSOCK; - } - spin_lock(&bedata->socket_lock); ret = get_request(bedata, &req_id); if (ret < 0) { spin_unlock(&bedata->socket_lock); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } req = RING_GET_REQUEST(&bedata->ring, req_id); @@ -684,7 +680,7 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len) bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; map->passive.status = PVCALLS_STATUS_BIND; - pvcalls_exit(); + pvcalls_exit_sock(sock); return 0; } @@ -695,21 +691,13 @@ int pvcalls_front_listen(struct socket *sock, int backlog) struct xen_pvcalls_request *req; int notify, req_id, ret; - pvcalls_enter(); - if (!pvcalls_front_dev) { - pvcalls_exit(); - return -ENOTCONN; - } + map = pvcalls_enter_sock(sock); + if (IS_ERR(map)) + return PTR_ERR(map); bedata = dev_get_drvdata(&pvcalls_front_dev->dev); - map = (struct sock_mapping *) sock->sk->sk_send_head; - if (!map) { - pvcalls_exit(); - return -ENOTSOCK; - } - if (map->passive.status != PVCALLS_STATUS_BIND) { - pvcalls_exit(); + pvcalls_exit_sock(sock); return -EOPNOTSUPP; } @@ -717,7 +705,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog) ret = get_request(bedata, &req_id); if (ret < 0) { spin_unlock(&bedata->socket_lock); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } req = RING_GET_REQUEST(&bedata->ring, req_id); @@ -741,7 +729,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog) bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; map->passive.status = PVCALLS_STATUS_LISTEN; - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } @@ -753,21 +741,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) struct xen_pvcalls_request *req; int notify, req_id, ret, evtchn, nonblock; - pvcalls_enter(); - if (!pvcalls_front_dev) { - pvcalls_exit(); - return -ENOTCONN; - } + map = pvcalls_enter_sock(sock); + if (IS_ERR(map)) + return PTR_ERR(map); bedata = dev_get_drvdata(&pvcalls_front_dev->dev); - map = (struct sock_mapping *) sock->sk->sk_send_head; - if (!map) { - pvcalls_exit(); - return -ENOTSOCK; - } - if (map->passive.status != PVCALLS_STATUS_LISTEN) { - pvcalls_exit(); + pvcalls_exit_sock(sock); return -EINVAL; } @@ -785,13 +765,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) goto received; } if (nonblock) { - pvcalls_exit(); + pvcalls_exit_sock(sock); return -EAGAIN; } if (wait_event_interruptible(map->passive.inflight_accept_req, !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags))) { - pvcalls_exit(); + pvcalls_exit_sock(sock); return -EINTR; } } @@ -802,7 +782,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); spin_unlock(&bedata->socket_lock); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } map2 = kzalloc(sizeof(*map2), GFP_ATOMIC); @@ -810,7 +790,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); spin_unlock(&bedata->socket_lock); - pvcalls_exit(); + pvcalls_exit_sock(sock); return -ENOMEM; } ret = create_active(map2, &evtchn); @@ -819,7 +799,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); spin_unlock(&bedata->socket_lock); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } list_add_tail(&map2->list, &bedata->socket_mappings); @@ -841,13 +821,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) /* We could check if we have received a response before returning. */ if (nonblock) { WRITE_ONCE(map->passive.inflight_req_id, req_id); - pvcalls_exit(); + pvcalls_exit_sock(sock); return -EAGAIN; } if (wait_event_interruptible(bedata->inflight_req, READ_ONCE(bedata->rsp[req_id].req_id) == req_id)) { - pvcalls_exit(); + pvcalls_exit_sock(sock); return -EINTR; } /* read req_id, then the content */ @@ -862,7 +842,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); pvcalls_front_free_map(bedata, map2); - pvcalls_exit(); + pvcalls_exit_sock(sock); return -ENOMEM; } newsock->sk->sk_send_head = (void *)map2; @@ -874,7 +854,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); wake_up(&map->passive.inflight_accept_req); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } @@ -965,23 +945,16 @@ unsigned int pvcalls_front_poll(struct file *file, struct socket *sock, struct sock_mapping *map; int ret; - pvcalls_enter(); - if (!pvcalls_front_dev) { - pvcalls_exit(); + map = pvcalls_enter_sock(sock); + if (IS_ERR(map)) return POLLNVAL; - } bedata = dev_get_drvdata(&pvcalls_front_dev->dev); - map = (struct sock_mapping *) sock->sk->sk_send_head; - if (!map) { - pvcalls_exit(); - return POLLNVAL; - } if (map->active_socket) ret = pvcalls_front_poll_active(file, bedata, map, wait); else ret = pvcalls_front_poll_passive(file, bedata, map, wait); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } @@ -995,25 +968,18 @@ int pvcalls_front_release(struct socket *sock) if (sock->sk == NULL) return 0; - pvcalls_enter(); - if (!pvcalls_front_dev) { - pvcalls_exit(); + map = pvcalls_enter_sock(sock); + if (IS_ERR(map) && PTR_ERR(map) == -ENOTCONN) return -EIO; - } - - bedata = dev_get_drvdata(&pvcalls_front_dev->dev); - - map = (struct sock_mapping *) sock->sk->sk_send_head; - if (map == NULL) { - pvcalls_exit(); + if (IS_ERR(map) && PTR_ERR(map) == -ENOTSOCK) return 0; - } + bedata = dev_get_drvdata(&pvcalls_front_dev->dev); spin_lock(&bedata->socket_lock); ret = get_request(bedata, &req_id); if (ret < 0) { spin_unlock(&bedata->socket_lock); - pvcalls_exit(); + pvcalls_exit_sock(sock); return ret; } sock->sk->sk_send_head = NULL; @@ -1043,10 +1009,10 @@ int pvcalls_front_release(struct socket *sock) /* * We need to make sure that sendmsg/recvmsg on this socket have * not started before we've cleared sk_send_head here. The - * easiest (though not optimal) way to guarantee this is to see - * that no pvcall (other than us) is in progress. + * easiest way to guarantee this is to see that no pvcalls + * (other than us) is in progress on this socket. */ - while (atomic_read(&pvcalls_refcount) > 1) + while (atomic_read(&map->refcount) > 1) cpu_relax(); pvcalls_front_free_map(bedata, map); -- 1.9.1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] pvcalls-front: wait for other operations to return when release passive sockets 2018-02-05 22:51 ` [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount Stefano Stabellini @ 2018-02-05 22:51 ` Stefano Stabellini 2018-02-12 13:39 ` Juergen Gross 2018-02-12 13:14 ` [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount Juergen Gross 1 sibling, 1 reply; 7+ messages in thread From: Stefano Stabellini @ 2018-02-05 22:51 UTC (permalink / raw) To: boris.ostrovsky, jgross Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini Passive sockets can have ongoing operations on them, specifically, we have two wait_event_interruptable calls in pvcalls_front_accept. Add two wake_up calls in pvcalls_front_release, then wait for the potential waiters to return and release the sock_mapping refcount. Signed-off-by: Stefano Stabellini <stefano@aporeto.com> --- drivers/xen/pvcalls-front.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c index 164d3ad..d32cac5 100644 --- a/drivers/xen/pvcalls-front.c +++ b/drivers/xen/pvcalls-front.c @@ -1017,6 +1017,12 @@ int pvcalls_front_release(struct socket *sock) pvcalls_front_free_map(bedata, map); } else { + wake_up(&bedata->inflight_req); + wake_up(&map->passive.inflight_accept_req); + + while (atomic_read(&map->refcount) > 1) + cpu_relax(); + spin_lock(&bedata->socket_lock); list_del(&map->list); spin_unlock(&bedata->socket_lock); -- 1.9.1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] pvcalls-front: wait for other operations to return when release passive sockets 2018-02-05 22:51 ` [PATCH 2/2] pvcalls-front: wait for other operations to return when release passive sockets Stefano Stabellini @ 2018-02-12 13:39 ` Juergen Gross 2018-02-13 2:07 ` Stefano Stabellini 0 siblings, 1 reply; 7+ messages in thread From: Juergen Gross @ 2018-02-12 13:39 UTC (permalink / raw) To: Stefano Stabellini, boris.ostrovsky Cc: xen-devel, linux-kernel, Stefano Stabellini On 05/02/18 23:51, Stefano Stabellini wrote: > Passive sockets can have ongoing operations on them, specifically, we > have two wait_event_interruptable calls in pvcalls_front_accept. > > Add two wake_up calls in pvcalls_front_release, then wait for the > potential waiters to return and release the sock_mapping refcount. > > Signed-off-by: Stefano Stabellini <stefano@aporeto.com> Acked-by: Juergen Gross <jgross@suse.com> Juergen ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] pvcalls-front: wait for other operations to return when release passive sockets 2018-02-12 13:39 ` Juergen Gross @ 2018-02-13 2:07 ` Stefano Stabellini 0 siblings, 0 replies; 7+ messages in thread From: Stefano Stabellini @ 2018-02-13 2:07 UTC (permalink / raw) To: Juergen Gross Cc: Stefano Stabellini, boris.ostrovsky, xen-devel, linux-kernel, Stefano Stabellini On Mon, 12 Feb 2018, Juergen Gross wrote: > On 05/02/18 23:51, Stefano Stabellini wrote: > > Passive sockets can have ongoing operations on them, specifically, we > > have two wait_event_interruptable calls in pvcalls_front_accept. > > > > Add two wake_up calls in pvcalls_front_release, then wait for the > > potential waiters to return and release the sock_mapping refcount. > > > > Signed-off-by: Stefano Stabellini <stefano@aporeto.com> > > Acked-by: Juergen Gross <jgross@suse.com> Thanks! ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount 2018-02-05 22:51 ` [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount Stefano Stabellini 2018-02-05 22:51 ` [PATCH 2/2] pvcalls-front: wait for other operations to return when release passive sockets Stefano Stabellini @ 2018-02-12 13:14 ` Juergen Gross 2018-02-13 2:06 ` Stefano Stabellini 1 sibling, 1 reply; 7+ messages in thread From: Juergen Gross @ 2018-02-12 13:14 UTC (permalink / raw) To: Stefano Stabellini, boris.ostrovsky Cc: xen-devel, linux-kernel, Stefano Stabellini On 05/02/18 23:51, Stefano Stabellini wrote: > Introduce a per sock_mapping refcount, in addition to the existing > global refcount. Thanks to the sock_mapping refcount, we can safely wait > for it to be 1 in pvcalls_front_release before freeing an active socket, > instead of waiting for the global refcount to be 1. > > Signed-off-by: Stefano Stabellini <stefano@aporeto.com> > --- > drivers/xen/pvcalls-front.c | 190 ++++++++++++++++++-------------------------- > 1 file changed, 78 insertions(+), 112 deletions(-) > > diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c > index 4c789e6..164d3ad 100644 > --- a/drivers/xen/pvcalls-front.c > +++ b/drivers/xen/pvcalls-front.c > @@ -60,6 +60,7 @@ struct sock_mapping { > bool active_socket; > struct list_head list; > struct socket *sock; > + atomic_t refcount; > union { > struct { > int irq; > @@ -93,6 +94,33 @@ struct sock_mapping { > }; > }; > > +static inline struct sock_mapping *pvcalls_enter_sock(struct socket *sock) > +{ > + struct sock_mapping *map = NULL; > + > + if (!pvcalls_front_dev || &pvcalls_front_dev->dev == NULL) Did you mean: if (!pvcalls_front_dev || !pvcalls_front_dev->dev) > + return ERR_PTR(-ENOTCONN); > + > + pvcalls_enter(); > + map = (struct sock_mapping *) sock->sk->sk_send_head; Style: no blank after the cast, please (multiple times). > + if (map == NULL) { > + pvcalls_exit() > + return ERR_PTR(-ENOTSOCK); > + } > + > + atomic_inc(&map->refcount); > + return map; > +} > + > +static inline void pvcalls_exit_sock(struct socket *sock) > +{ > + struct sock_mapping *map = NULL; > + > + map = (struct sock_mapping *) sock->sk->sk_send_head; > + atomic_dec(&map->refcount); > + pvcalls_exit(); > +} > + > static inline int get_request(struct pvcalls_bedata *bedata, int *req_id) > { > *req_id = bedata->ring.req_prod_pvt & (RING_SIZE(&bedata->ring) - 1); > @@ -369,31 +397,23 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr, > if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) > return -EOPNOTSUPP; > > - pvcalls_enter(); > - if (!pvcalls_front_dev) { > - pvcalls_exit(); > - return -ENOTCONN; > - } > + map = pvcalls_enter_sock(sock); > + if (IS_ERR(map)) > + return PTR_ERR(map); > > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > - map = (struct sock_mapping *)sock->sk->sk_send_head; > - if (!map) { > - pvcalls_exit(); > - return -ENOTSOCK; > - } > - > spin_lock(&bedata->socket_lock); > ret = get_request(bedata, &req_id); > if (ret < 0) { > spin_unlock(&bedata->socket_lock); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > ret = create_active(map, &evtchn); > if (ret < 0) { > spin_unlock(&bedata->socket_lock); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > > @@ -423,7 +443,7 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr, > smp_rmb(); > ret = bedata->rsp[req_id].ret; > bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > > @@ -488,23 +508,15 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, > if (flags & (MSG_CONFIRM|MSG_DONTROUTE|MSG_EOR|MSG_OOB)) > return -EOPNOTSUPP; > > - pvcalls_enter(); > - if (!pvcalls_front_dev) { > - pvcalls_exit(); > - return -ENOTCONN; > - } > + map = pvcalls_enter_sock(sock); > + if (IS_ERR(map)) > + return PTR_ERR(map); > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > - if (!map) { > - pvcalls_exit(); > - return -ENOTSOCK; > - } > - > mutex_lock(&map->active.out_mutex); > if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) { > mutex_unlock(&map->active.out_mutex); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return -EAGAIN; > } > if (len > INT_MAX) > @@ -526,7 +538,7 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, > tot_sent = sent; > > mutex_unlock(&map->active.out_mutex); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return tot_sent; > } > > @@ -591,19 +603,11 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, > if (flags & (MSG_CMSG_CLOEXEC|MSG_ERRQUEUE|MSG_OOB|MSG_TRUNC)) > return -EOPNOTSUPP; > > - pvcalls_enter(); > - if (!pvcalls_front_dev) { > - pvcalls_exit(); > - return -ENOTCONN; > - } > + map = pvcalls_enter_sock(sock); > + if (IS_ERR(map)) > + return PTR_ERR(map); > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > - if (!map) { > - pvcalls_exit(); > - return -ENOTSOCK; > - } > - > mutex_lock(&map->active.in_mutex); > if (len > XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER)) > len = XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER); > @@ -623,7 +627,7 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, > ret = 0; > > mutex_unlock(&map->active.in_mutex); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > > @@ -637,24 +641,16 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len) > if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) > return -EOPNOTSUPP; > > - pvcalls_enter(); > - if (!pvcalls_front_dev) { > - pvcalls_exit(); > - return -ENOTCONN; > - } > + map = pvcalls_enter_sock(sock); > + if (IS_ERR(map)) > + return PTR_ERR(map); > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > - if (map == NULL) { > - pvcalls_exit(); > - return -ENOTSOCK; > - } > - > spin_lock(&bedata->socket_lock); > ret = get_request(bedata, &req_id); > if (ret < 0) { > spin_unlock(&bedata->socket_lock); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > req = RING_GET_REQUEST(&bedata->ring, req_id); > @@ -684,7 +680,7 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len) > bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; > > map->passive.status = PVCALLS_STATUS_BIND; > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return 0; > } > > @@ -695,21 +691,13 @@ int pvcalls_front_listen(struct socket *sock, int backlog) > struct xen_pvcalls_request *req; > int notify, req_id, ret; > > - pvcalls_enter(); > - if (!pvcalls_front_dev) { > - pvcalls_exit(); > - return -ENOTCONN; > - } > + map = pvcalls_enter_sock(sock); > + if (IS_ERR(map)) > + return PTR_ERR(map); > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > - if (!map) { > - pvcalls_exit(); > - return -ENOTSOCK; > - } > - > if (map->passive.status != PVCALLS_STATUS_BIND) { > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return -EOPNOTSUPP; > } > > @@ -717,7 +705,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog) > ret = get_request(bedata, &req_id); > if (ret < 0) { > spin_unlock(&bedata->socket_lock); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > req = RING_GET_REQUEST(&bedata->ring, req_id); > @@ -741,7 +729,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog) > bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; > > map->passive.status = PVCALLS_STATUS_LISTEN; > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > > @@ -753,21 +741,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > struct xen_pvcalls_request *req; > int notify, req_id, ret, evtchn, nonblock; > > - pvcalls_enter(); > - if (!pvcalls_front_dev) { > - pvcalls_exit(); > - return -ENOTCONN; > - } > + map = pvcalls_enter_sock(sock); > + if (IS_ERR(map)) > + return PTR_ERR(map); > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > - if (!map) { > - pvcalls_exit(); > - return -ENOTSOCK; > - } > - > if (map->passive.status != PVCALLS_STATUS_LISTEN) { > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return -EINVAL; > } > > @@ -785,13 +765,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > goto received; > } > if (nonblock) { > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return -EAGAIN; > } > if (wait_event_interruptible(map->passive.inflight_accept_req, > !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > (void *)&map->passive.flags))) { > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return -EINTR; > } > } > @@ -802,7 +782,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > (void *)&map->passive.flags); > spin_unlock(&bedata->socket_lock); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > map2 = kzalloc(sizeof(*map2), GFP_ATOMIC); > @@ -810,7 +790,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > (void *)&map->passive.flags); > spin_unlock(&bedata->socket_lock); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return -ENOMEM; > } > ret = create_active(map2, &evtchn); > @@ -819,7 +799,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > (void *)&map->passive.flags); > spin_unlock(&bedata->socket_lock); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > list_add_tail(&map2->list, &bedata->socket_mappings); > @@ -841,13 +821,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > /* We could check if we have received a response before returning. */ > if (nonblock) { > WRITE_ONCE(map->passive.inflight_req_id, req_id); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return -EAGAIN; > } > > if (wait_event_interruptible(bedata->inflight_req, > READ_ONCE(bedata->rsp[req_id].req_id) == req_id)) { > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return -EINTR; > } > /* read req_id, then the content */ > @@ -862,7 +842,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > (void *)&map->passive.flags); > pvcalls_front_free_map(bedata, map2); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return -ENOMEM; > } > newsock->sk->sk_send_head = (void *)map2; > @@ -874,7 +854,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); > wake_up(&map->passive.inflight_accept_req); > > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > > @@ -965,23 +945,16 @@ unsigned int pvcalls_front_poll(struct file *file, struct socket *sock, > struct sock_mapping *map; > int ret; > > - pvcalls_enter(); > - if (!pvcalls_front_dev) { > - pvcalls_exit(); > + map = pvcalls_enter_sock(sock); > + if (IS_ERR(map)) > return POLLNVAL; > - } > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > - if (!map) { > - pvcalls_exit(); > - return POLLNVAL; > - } > if (map->active_socket) > ret = pvcalls_front_poll_active(file, bedata, map, wait); > else > ret = pvcalls_front_poll_passive(file, bedata, map, wait); > - pvcalls_exit(); > + pvcalls_exit_sock(sock); > return ret; > } > > @@ -995,25 +968,18 @@ int pvcalls_front_release(struct socket *sock) > if (sock->sk == NULL) > return 0; > > - pvcalls_enter(); > - if (!pvcalls_front_dev) { > - pvcalls_exit(); > + map = pvcalls_enter_sock(sock); > + if (IS_ERR(map) && PTR_ERR(map) == -ENOTCONN) > return -EIO; > - } > - > - bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > - > - map = (struct sock_mapping *) sock->sk->sk_send_head; > - if (map == NULL) { > - pvcalls_exit(); > + if (IS_ERR(map) && PTR_ERR(map) == -ENOTSOCK) > return 0; Hmm, what about: if (IS_ERR(map)) { if (PTR_ERR(map) == -ENOTCONN) return -EIO; else return 0; } Juergen ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount 2018-02-12 13:14 ` [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount Juergen Gross @ 2018-02-13 2:06 ` Stefano Stabellini 0 siblings, 0 replies; 7+ messages in thread From: Stefano Stabellini @ 2018-02-13 2:06 UTC (permalink / raw) To: Juergen Gross Cc: Stefano Stabellini, boris.ostrovsky, xen-devel, linux-kernel, Stefano Stabellini On Mon, 12 Feb 2018, Juergen Gross wrote: > On 05/02/18 23:51, Stefano Stabellini wrote: > > Introduce a per sock_mapping refcount, in addition to the existing > > global refcount. Thanks to the sock_mapping refcount, we can safely wait > > for it to be 1 in pvcalls_front_release before freeing an active socket, > > instead of waiting for the global refcount to be 1. > > > > Signed-off-by: Stefano Stabellini <stefano@aporeto.com> > > --- > > drivers/xen/pvcalls-front.c | 190 ++++++++++++++++++-------------------------- > > 1 file changed, 78 insertions(+), 112 deletions(-) > > > > diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c > > index 4c789e6..164d3ad 100644 > > --- a/drivers/xen/pvcalls-front.c > > +++ b/drivers/xen/pvcalls-front.c > > @@ -60,6 +60,7 @@ struct sock_mapping { > > bool active_socket; > > struct list_head list; > > struct socket *sock; > > + atomic_t refcount; > > union { > > struct { > > int irq; > > @@ -93,6 +94,33 @@ struct sock_mapping { > > }; > > }; > > > > +static inline struct sock_mapping *pvcalls_enter_sock(struct socket *sock) > > +{ > > + struct sock_mapping *map = NULL; > > + > > + if (!pvcalls_front_dev || &pvcalls_front_dev->dev == NULL) > > Did you mean: > if (!pvcalls_front_dev || !pvcalls_front_dev->dev) I actually meant: if (!pvcalls_front_dev || dev_get_drvdata(&pvcalls_front_dev->dev) == NULL) > > + return ERR_PTR(-ENOTCONN); > > + > > + pvcalls_enter(); > > + map = (struct sock_mapping *) sock->sk->sk_send_head; > > Style: no blank after the cast, please (multiple times). OK, I'll fix them all > > + if (map == NULL) { > > + pvcalls_exit() > > + return ERR_PTR(-ENOTSOCK); > > + } > > + > > + atomic_inc(&map->refcount); > > + return map; > > +} > > + > > +static inline void pvcalls_exit_sock(struct socket *sock) > > +{ > > + struct sock_mapping *map = NULL; > > + > > + map = (struct sock_mapping *) sock->sk->sk_send_head; > > + atomic_dec(&map->refcount); > > + pvcalls_exit(); > > +} > > + > > static inline int get_request(struct pvcalls_bedata *bedata, int *req_id) > > { > > *req_id = bedata->ring.req_prod_pvt & (RING_SIZE(&bedata->ring) - 1); > > @@ -369,31 +397,23 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr, > > if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) > > return -EOPNOTSUPP; > > > > - pvcalls_enter(); > > - if (!pvcalls_front_dev) { > > - pvcalls_exit(); > > - return -ENOTCONN; > > - } > > + map = pvcalls_enter_sock(sock); > > + if (IS_ERR(map)) > > + return PTR_ERR(map); > > > > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > > > - map = (struct sock_mapping *)sock->sk->sk_send_head; > > - if (!map) { > > - pvcalls_exit(); > > - return -ENOTSOCK; > > - } > > - > > spin_lock(&bedata->socket_lock); > > ret = get_request(bedata, &req_id); > > if (ret < 0) { > > spin_unlock(&bedata->socket_lock); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > ret = create_active(map, &evtchn); > > if (ret < 0) { > > spin_unlock(&bedata->socket_lock); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > > > @@ -423,7 +443,7 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr, > > smp_rmb(); > > ret = bedata->rsp[req_id].ret; > > bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > > > @@ -488,23 +508,15 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, > > if (flags & (MSG_CONFIRM|MSG_DONTROUTE|MSG_EOR|MSG_OOB)) > > return -EOPNOTSUPP; > > > > - pvcalls_enter(); > > - if (!pvcalls_front_dev) { > > - pvcalls_exit(); > > - return -ENOTCONN; > > - } > > + map = pvcalls_enter_sock(sock); > > + if (IS_ERR(map)) > > + return PTR_ERR(map); > > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > > - if (!map) { > > - pvcalls_exit(); > > - return -ENOTSOCK; > > - } > > - > > mutex_lock(&map->active.out_mutex); > > if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) { > > mutex_unlock(&map->active.out_mutex); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return -EAGAIN; > > } > > if (len > INT_MAX) > > @@ -526,7 +538,7 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, > > tot_sent = sent; > > > > mutex_unlock(&map->active.out_mutex); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return tot_sent; > > } > > > > @@ -591,19 +603,11 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, > > if (flags & (MSG_CMSG_CLOEXEC|MSG_ERRQUEUE|MSG_OOB|MSG_TRUNC)) > > return -EOPNOTSUPP; > > > > - pvcalls_enter(); > > - if (!pvcalls_front_dev) { > > - pvcalls_exit(); > > - return -ENOTCONN; > > - } > > + map = pvcalls_enter_sock(sock); > > + if (IS_ERR(map)) > > + return PTR_ERR(map); > > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > > - if (!map) { > > - pvcalls_exit(); > > - return -ENOTSOCK; > > - } > > - > > mutex_lock(&map->active.in_mutex); > > if (len > XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER)) > > len = XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER); > > @@ -623,7 +627,7 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, > > ret = 0; > > > > mutex_unlock(&map->active.in_mutex); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > > > @@ -637,24 +641,16 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len) > > if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM) > > return -EOPNOTSUPP; > > > > - pvcalls_enter(); > > - if (!pvcalls_front_dev) { > > - pvcalls_exit(); > > - return -ENOTCONN; > > - } > > + map = pvcalls_enter_sock(sock); > > + if (IS_ERR(map)) > > + return PTR_ERR(map); > > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > > - if (map == NULL) { > > - pvcalls_exit(); > > - return -ENOTSOCK; > > - } > > - > > spin_lock(&bedata->socket_lock); > > ret = get_request(bedata, &req_id); > > if (ret < 0) { > > spin_unlock(&bedata->socket_lock); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > req = RING_GET_REQUEST(&bedata->ring, req_id); > > @@ -684,7 +680,7 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len) > > bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; > > > > map->passive.status = PVCALLS_STATUS_BIND; > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return 0; > > } > > > > @@ -695,21 +691,13 @@ int pvcalls_front_listen(struct socket *sock, int backlog) > > struct xen_pvcalls_request *req; > > int notify, req_id, ret; > > > > - pvcalls_enter(); > > - if (!pvcalls_front_dev) { > > - pvcalls_exit(); > > - return -ENOTCONN; > > - } > > + map = pvcalls_enter_sock(sock); > > + if (IS_ERR(map)) > > + return PTR_ERR(map); > > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > > - if (!map) { > > - pvcalls_exit(); > > - return -ENOTSOCK; > > - } > > - > > if (map->passive.status != PVCALLS_STATUS_BIND) { > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return -EOPNOTSUPP; > > } > > > > @@ -717,7 +705,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog) > > ret = get_request(bedata, &req_id); > > if (ret < 0) { > > spin_unlock(&bedata->socket_lock); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > req = RING_GET_REQUEST(&bedata->ring, req_id); > > @@ -741,7 +729,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog) > > bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID; > > > > map->passive.status = PVCALLS_STATUS_LISTEN; > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > > > @@ -753,21 +741,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > > struct xen_pvcalls_request *req; > > int notify, req_id, ret, evtchn, nonblock; > > > > - pvcalls_enter(); > > - if (!pvcalls_front_dev) { > > - pvcalls_exit(); > > - return -ENOTCONN; > > - } > > + map = pvcalls_enter_sock(sock); > > + if (IS_ERR(map)) > > + return PTR_ERR(map); > > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > > - if (!map) { > > - pvcalls_exit(); > > - return -ENOTSOCK; > > - } > > - > > if (map->passive.status != PVCALLS_STATUS_LISTEN) { > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return -EINVAL; > > } > > > > @@ -785,13 +765,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > > goto received; > > } > > if (nonblock) { > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return -EAGAIN; > > } > > if (wait_event_interruptible(map->passive.inflight_accept_req, > > !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > > (void *)&map->passive.flags))) { > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return -EINTR; > > } > > } > > @@ -802,7 +782,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > > (void *)&map->passive.flags); > > spin_unlock(&bedata->socket_lock); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > map2 = kzalloc(sizeof(*map2), GFP_ATOMIC); > > @@ -810,7 +790,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > > (void *)&map->passive.flags); > > spin_unlock(&bedata->socket_lock); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return -ENOMEM; > > } > > ret = create_active(map2, &evtchn); > > @@ -819,7 +799,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > > (void *)&map->passive.flags); > > spin_unlock(&bedata->socket_lock); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > list_add_tail(&map2->list, &bedata->socket_mappings); > > @@ -841,13 +821,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > > /* We could check if we have received a response before returning. */ > > if (nonblock) { > > WRITE_ONCE(map->passive.inflight_req_id, req_id); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return -EAGAIN; > > } > > > > if (wait_event_interruptible(bedata->inflight_req, > > READ_ONCE(bedata->rsp[req_id].req_id) == req_id)) { > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return -EINTR; > > } > > /* read req_id, then the content */ > > @@ -862,7 +842,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, > > (void *)&map->passive.flags); > > pvcalls_front_free_map(bedata, map2); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return -ENOMEM; > > } > > newsock->sk->sk_send_head = (void *)map2; > > @@ -874,7 +854,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) > > clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); > > wake_up(&map->passive.inflight_accept_req); > > > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > > > @@ -965,23 +945,16 @@ unsigned int pvcalls_front_poll(struct file *file, struct socket *sock, > > struct sock_mapping *map; > > int ret; > > > > - pvcalls_enter(); > > - if (!pvcalls_front_dev) { > > - pvcalls_exit(); > > + map = pvcalls_enter_sock(sock); > > + if (IS_ERR(map)) > > return POLLNVAL; > > - } > > bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > > - if (!map) { > > - pvcalls_exit(); > > - return POLLNVAL; > > - } > > if (map->active_socket) > > ret = pvcalls_front_poll_active(file, bedata, map, wait); > > else > > ret = pvcalls_front_poll_passive(file, bedata, map, wait); > > - pvcalls_exit(); > > + pvcalls_exit_sock(sock); > > return ret; > > } > > > > @@ -995,25 +968,18 @@ int pvcalls_front_release(struct socket *sock) > > if (sock->sk == NULL) > > return 0; > > > > - pvcalls_enter(); > > - if (!pvcalls_front_dev) { > > - pvcalls_exit(); > > + map = pvcalls_enter_sock(sock); > > + if (IS_ERR(map) && PTR_ERR(map) == -ENOTCONN) > > return -EIO; > > - } > > - > > - bedata = dev_get_drvdata(&pvcalls_front_dev->dev); > > - > > - map = (struct sock_mapping *) sock->sk->sk_send_head; > > - if (map == NULL) { > > - pvcalls_exit(); > > + if (IS_ERR(map) && PTR_ERR(map) == -ENOTSOCK) > > return 0; > > Hmm, what about: > > if (IS_ERR(map)) { > if (PTR_ERR(map) == -ENOTCONN) > return -EIO; > else > return 0; > } Sounds good. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2018-02-13 2:07 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-02-05 22:51 [PATCH 0/2] pvcalls-front improvements Stefano Stabellini 2018-02-05 22:51 ` [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount Stefano Stabellini 2018-02-05 22:51 ` [PATCH 2/2] pvcalls-front: wait for other operations to return when release passive sockets Stefano Stabellini 2018-02-12 13:39 ` Juergen Gross 2018-02-13 2:07 ` Stefano Stabellini 2018-02-12 13:14 ` [PATCH 1/2] pvcalls-front: introduce a per sock_mapping refcount Juergen Gross 2018-02-13 2:06 ` Stefano Stabellini
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome