[CRIU] Re: [RFC PATCH] posix timers: allocate timer id per task

Pavel Emelyanov xemul at parallels.com
Mon Oct 15 11:39:57 EDT 2012


On 10/15/2012 07:36 PM, Stanislav Kinsbursky wrote:
> 15.10.2012 19:33, Pavel Emelyanov пишет:
>> On 10/15/2012 07:30 PM, Stanislav Kinsbursky wrote:
>>> 15.10.2012 19:26, Pavel Emelyanov пишет:
>>>> On 10/15/2012 07:24 PM, Stanislav Kinsbursky wrote:
>>>>> 15.10.2012 19:16, Pavel Emelyanov пишет:
>>>>>> On 10/15/2012 06:01 PM, Stanislav Kinsbursky wrote:
>>>>>>> This patch replaces global idr with global hash table for posix timers and
>>>>>>> makes timer ids unique not globally, but per task. Next free timer id is type
>>>>>>> of integer and stored on signal struct (posix_timer_id). If free timer id
>>>>>>> reaches negative value on timer creation, it will be dropped to zero and
>>>>>>> -EAGAIN will be returned to user.
>>>>>>>
>>>>>>> Hash table is size of page (4KB).
>>>>>>>
>>>>>>> Key is constructed as follows:
>>>>>>> key = hash_ptr(current->signal) ^ hash_32(posix_timer_id);
>>>>>>>
>>>>>>> ---
>>>>>>>     include/linux/posix-timers.h |    1
>>>>>>>     include/linux/sched.h        |    4 +-
>>>>>>>     kernel/posix-timers.c        |  112 ++++++++++++++++++++++++++++--------------
>>>>>>>     3 files changed, 78 insertions(+), 39 deletions(-)
>>>>>>>
>>>>>>
>>>>>>
>>>>>>> +{
>>>>>>> +	struct signal_struct *sig = current->signal;
>>>>>>> +	struct hlist_head *head;
>>>>>>> +	int ret = -ENOENT;
>>>>>>> +
>>>>>>> +	do {
>>>>>>> +		spin_lock(&hash_lock);
>>>>>>> +		head = &posix_timers_hashtable[hash(sig, sig->posix_timer_id)];
>>>>>>> +		if (__posix_timers_find(head, sig, sig->posix_timer_id) == NULL) {
>>>>>>> +			hlist_add_head(&timer->t_hash, head);
>>>>>>> +			ret = sig->posix_timer_id++;
>>>>>>> +		} else if (++sig->posix_timer_id < 0) {
>>>>>>> +			sig->posix_timer_id = 0;
>>>>>>> +			ret = -EAGAIN;
>>>>>>
>>>>>> What for? Overflow is OK, no need in restart.
>>>>>>
>>>>>
>>>>> I was thinking, that we need some way to stop here in case of corner case, when
>>>>> all id's are busy.
>>>>> I'm don't think that anyone can reach even INT_MAX timers in one task, so
>>>>> INT_MAX looks enough. This "EGAIN" will be returned to user.
>>>>
>>>> while (1) {
>>>> 	add_timer()
>>>> 	del_timer()
>>>> }
>>>>
>>>> will overflow it very fast.
>>>>
>>>
>>> Sure. And add_timer() caller will receive -EAGAIN.
>>
>> It didn't behave _that_ _before_ this patch.
>>
> 
> Yes, it did.
> 
> # man timer_create
> 
> ERRORS
>         EAGAIN Temporary error during kernel allocation of timer structures.

Rule #1 in kernel programming -- never ever thing kernel works it is documented
to work (c).

Stas, it did _NOT_ behave like that in the test I provided, it should _NOT_ start
doing so.

> 
>>> This is already a part of timer_create() API.
>>
>> It doesn't mean you can report "I'm confused, try one more time please".
>>
> 
> O_o
> 
>>> Actually, I can check for 0 after add and return -EAGAIN in this case.
>>
>> -1
>>
> 
> Please, share the better idea, if you have it.

Remember ID we had on signal-> when started, then report error in case we
meet it again.



More information about the CRIU mailing list