[CRIU] [PATCH RFC 21/30] unix: Wait a peer using task_st futex
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Nov 29 03:04:44 PST 2016
On 08.11.2016 16:07, Pavel Emelyanov wrote:
> 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 idea is to use task_st futex for waiting of every events.
This allows to sleep on it. Impossible to sleep on a bunch of
futexes of different event types at once.
>> 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