[CRIU] [PATCH 4/5] timerfd: Implement c/r procedure, v2

Pavel Emelyanov xemul at parallels.com
Fri Jun 27 08:38:11 PDT 2014


On 06/27/2014 01:57 PM, Cyrill Gorcunov wrote:
> On Fri, Jun 27, 2014 at 01:24:30AM +0400, Pavel Emelyanov wrote:
>> On 06/27/2014 01:11 AM, Cyrill Gorcunov wrote:
>>> On Fri, Jun 27, 2014 at 01:07:48AM +0400, Pavel Emelyanov wrote:
>>>>> +
>>>>> +		t = rst_mem_alloc(sizeof(*t), RM_PRIVATE);
>>>>
>>>> Why not in post_open callback of timerfd ops?
>>>
>>> It must be sequential slab of restorer memory.
>>
>> Make it the same as in tcp sockets: post_open_inet_sk->rst_tcp_socks_add.
>> It copies memory, but a) there are quite a few of timerfd-s and b) we'll
>> have more reasons to optimize this.
> 
> Attached.

> +static int timerfd_post_open(struct file_desc *d, int fd)
> +{
> +	struct timerfd_info *info = container_of(d, struct timerfd_info, d);
> +	TimerfdEntry *tfe = info->tfe;
> +	struct restore_timerfd *t;
> +
> +	rst_timerfd_nr++;
> +	rst_timerfd = xrealloc(rst_timerfd, rst_timerfd_len());
> +	if (!rst_timerfd)
> +		return -ENOMEM;
> +
> +	t = &rst_timerfd[rst_timerfd_nr - 1];
> +	t->fd				= fd;
> +	t->ticks			= (unsigned long)tfe->ticks;
> +	t->settime_flags		= tfe->settime_flags;
> +	t->val.it_interval.tv_sec	= (time_t)tfe->isec;
> +	t->val.it_interval.tv_nsec	= (long)tfe->insec;
> +	t->val.it_value.tv_sec		= (time_t)tfe->vsec;
> +	t->val.it_value.tv_nsec		= (long)tfe->vnsec;

How about TFD_TIMER_ABSTIME adjustments like in timerfd_open?

> +
> +	return 0;
> +}



> 
> +static int timerfd_open(struct file_desc *d)
> +{
> +	struct itimerspec v = { };

This v is write-only variable here.

> +	struct timerfd_info *info;
> +	TimerfdEntry *tfe;
> +	int tmp = -1;
> +
> +	info = container_of(d, struct timerfd_info, d);
> +	tfe = info->tfe;
> +	pr_info("Restoring id %#x clockid %d settime_flags %x ticks %llu "
> +		"it_value(%llu, %llu) it_interval(%llu, %llu)\n",
> +		tfe->id, tfe->clockid, tfe->settime_flags, (unsigned long long)tfe->ticks,
> +		(unsigned long long)tfe->vsec, (unsigned long long)tfe->vnsec,
> +		(unsigned long long)tfe->isec, (unsigned long long)tfe->insec);
> +
> +	tmp = timerfd_create(tfe->clockid, 0);
> +	if (tmp < 0) {
> +		pr_perror("Can't create for %#x\n", tfe->id);
> +		return -1;
> +	}
> +
> +	v.it_interval.tv_sec	= (time_t)tfe->isec;
> +	v.it_interval.tv_nsec	= (long)tfe->insec;
> +
> +	v.it_value.tv_sec	= (time_t)tfe->vsec;
> +	v.it_value.tv_nsec	= (long)tfe->vnsec;
> +
> +	if (tfe->settime_flags & TFD_TIMER_ABSTIME) {
> +		struct timespec ts = { };

So is ts.

> +
> +		/*
> +		 * We might need to adjust value because the checkpoint
> +		 * and restore procedure takes some time itself. Note
> +		 * we don't adjust nanoseconds, since the result may
> +		 * overflow the limit NSEC_PER_SEC FIXME
> +		 */
> +		if (clock_gettime(tfe->clockid, &ts)) {
> +			pr_perror("Can't get current time");
> +			goto err_close;
> +		}
> +
> +		v.it_value.tv_sec += (time_t)ts.tv_sec;
> +
> +		pr_debug("Ajust id %#x it_value(%llu, %llu) -> it_value(%llu, %llu)\n",
> +			 tfe->id, (unsigned long long)ts.tv_sec,
> +			 (unsigned long long)ts.tv_nsec,
> +			 (unsigned long long)v.it_value.tv_sec,
> +			 (unsigned long long)v.it_value.tv_nsec);
> +	}
> +
> +	if (rst_file_params(tmp, tfe->fown, tfe->flags)) {
> +		pr_perror("Can't restore params for %#x", tfe->id);
> +		goto err_close;
> +	}
> +
> +	return tmp;
> +
> +err_close:
> +	close_safe(&tmp);
> +	return -1;
> +}
> +

> +static struct file_desc_ops timerfd_desc_ops = {
> +	.type		= FD_TYPES__TIMERFD,
> +	.open		= timerfd_open,

Please write comment why we need post_open for timerfd-s.

> +	.post_open	= timerfd_post_open,
> +};
> +

> +static int timerfd_arm(struct task_restore_args *args)
> +{
> +	int i, ret;
> +
> +	for (i = 0; i < args->timerfd_n; i++) {
> +		struct restore_timerfd *t = &args->timerfd[i];
> +
> +		pr_debug("timerfd: arm for fd %d (%d)\n", t->fd, i);
> +
> +		ret  = sys_ioctl(t->fd, TFD_IOC_SET_TICKS, (unsigned long)&t->ticks);

Ticks can be restored in timerfd_open, can't they?

> +		ret |= sys_timerfd_settime(t->fd, t->settime_flags, &t->val, NULL);
> +		if (ret) {
> +			pr_err("Can't restore ticks/time for timerfd - %d\n", i);
> +			return ret;
> +		}
> +	}
> +	return 0;
> +}
> +




More information about the CRIU mailing list