[CRIU] [PATCH RFC 21/30] unix: Wait a peer using task_st futex

Pavel Emelyanov xemul at virtuozzo.com
Tue Nov 8 05:07:17 PST 2016


On 11/01/2016 05:33 PM, Kirill Tkhai wrote:
> Use new task_st futex notifier instead of per-socket.

I don't get this change. Why can't we wait on per-socket lock
and should wait on per-task one?

> The step to make open file non-blocking but task_st.
> 
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
>  criu/sk-unix.c |   38 +++++++++++++++++++++++++++-----------
>  1 file changed, 27 insertions(+), 11 deletions(-)
> 
> diff --git a/criu/sk-unix.c b/criu/sk-unix.c
> index a3301fc..49720da 100644
> --- a/criu/sk-unix.c
> +++ b/criu/sk-unix.c
> @@ -785,13 +785,6 @@ struct unix_sk_info {
>  	struct list_head node; /* To link in peer's connected list  */
>  
>  	/*
> -	 * Futex to signal when the socket is prepared. In particular, we
> -	 * signal after bind()ing the socket if it is not in TCP_LISTEN, or
> -	 * after listen() if the socket is in TCP_LISTEN.
> -	 */
> -	futex_t prepared;
> -
> -	/*
>  	 * For DGRAM sockets with queues, we should only restore the queue
>  	 * once although it may be open by more than one tid. This is the peer
>  	 * that should do the queueing.
> @@ -814,6 +807,29 @@ static struct unix_sk_info *find_unix_sk_by_ino(int ino)
>  	return NULL;
>  }
>  
> +static int wake_connected_sockets(struct unix_sk_info *ui)
> +{
> +	struct fdinfo_list_entry *fle;
> +	struct unix_sk_info *tmp;
> +
> +	list_for_each_entry(tmp, &ui->connected, node) {
> +		fle = file_master(&tmp->d);
> +		set_fds_event(fle->pid);
> +	}
> +	return 0;
> +}
> +
> +static bool peer_is_not_prepared(struct unix_sk_info *peer)
> +{
> +	struct fdinfo_list_entry *fle;
> +	fle = file_master(&peer->d);
> +
> +	if (peer->ue->state != TCP_LISTEN)
> +		return (fle->stage < FLE_BOUND) ? true : false;
> +	else
> +		return (fle->stage < FLE_LISTEN) ? true : false;
> +}
> +
>  static int shutdown_unix_sk(int sk, struct unix_sk_info *ui)
>  {
>  	int how;
> @@ -886,7 +902,8 @@ static int post_open_unix_sk(struct file_desc *d, int fd)
>  
>  	/* Skip external sockets */
>  	if (!list_empty(&peer->d.fd_info_head))
> -		futex_wait_while(&peer->prepared, 0);
> +		while (peer_is_not_prepared(peer))
> +			wait_fds_event();
>  
>  	if (ui->ue->uflags & USK_INHERIT)
>  		return 0;
> @@ -1028,9 +1045,9 @@ static int bind_unix_sk(int sk, struct unix_sk_info *ui)
>  	}
>  
>  	if (ui->ue->state != TCP_LISTEN) {
> -		futex_set_and_wake(&ui->prepared, 1);
>  		fle = file_master(&ui->d);
>  		fle->stage = FLE_BOUND;
> +		wake_connected_sockets(ui);
>  	}
>  
>  	ret = 0;
> @@ -1240,9 +1257,9 @@ static int open_unixsk_standalone(struct unix_sk_info *ui)
>  			pr_perror("Can't make usk listen");
>  			return -1;
>  		}
> -		futex_set_and_wake(&ui->prepared, 1);
>  		fle = file_master(&ui->d);
>  		fle->stage = FLE_LISTEN;
> +		wake_connected_sockets(ui);
>  	}
>  out:
>  	if (rst_file_params(sk, ui->ue->fown, ui->ue->flags))
> @@ -1347,7 +1364,6 @@ static int collect_one_unixsk(void *o, ProtobufCMessage *base, struct cr_img *i)
>  	} else
>  		ui->name = NULL;
>  
> -	futex_init(&ui->prepared);
>  	ui->queuer = 0;
>  	ui->peer = NULL;
>  	INIT_LIST_HEAD(&ui->connected);
> 
> .
> 



More information about the CRIU mailing list