[Devel] [PATCH] mm: high order allocation detector

Kirill Tkhai ktkhai at virtuozzo.com
Tue Aug 31 17:38:24 MSK 2021


On 31.08.2021 17:16, Nikita Yushchenko wrote:
>>> +static void hoad_reset_counter(struct work_struct *work)
>>> +{
>>> +    struct hoad_order_info *hoi = container_of(work,
>>> +            struct hoad_order_info, reset_counter_work.work);
>>> +
>>> +    atomic_set(&hoi->counter, 0);
>>
>> Do we really need work to do such simple action? Why plain timer is not enough?
> 
> Ok, will convert to timer.
> 
>>> +static void hoad_send_uevent(struct work_struct *work)
>>> +{
>>> +    char order_string[16];
>>> +    char *envp[] = { order_string, NULL };
>>
>> Please, use new lines after declarations.
> 
> Ok
> 
>>
>>> +    sprintf(order_string, "ORDER=%d", hoad_uevent_order);
>>> +    kobject_uevent_env(hoad_kobj, KOBJ_CHANGE, envp);
>>> +}
>>> +static DECLARE_WORK(hoad_send_uevent_work, hoad_send_uevent);
>>> +
>>> +static void hoad_resume(struct work_struct *work)
>>> +{
>>> +    hoad_uevent_order = 0;
>>
>> The same is here: do we really need work here?
> 
> Ok, will convert to timer
> 
>>> +    if (oldhoi) {
>>> +        synchronize_rcu();
>>> +        cancel_delayed_work_sync(&oldhoi->reset_counter_work);
>>
>> Why do we completely cancel this? We possible updated single order entity,
>> don't other orders still need to be reset?
> 
> It is per-order, and accesses hoad_order_info container.
> Cancelling one for 'oldhoi' before freeing 'oldhoi'.
> 
> After converting to timer, this situation will remain.
> 
>>> +            p += sprintf(p, "order %u: %u/%u in %u/%u msecs\n",
>>> +                    order, counter, hoi->max_allocs,
>>> +                    msecs, jiffies_to_msecs(hoi->interval));
>>
>> Any guarantees all printed in this function data fits provided @buf?
> 
> Yes, buf is a full page, number of orders is limited (<20), this leaves >200 bytes per order, which is more than enough.
> 
>>> +        if (msecs > 1000 * 60 * 60 * 24 * 5)
>>
>> Every magic number should be described with #define.
> 
> Do you want separate defines for every number?
> Or things like "5 * MSECS_PER_DAY' can work?

MSECS_PER_DAY looks good.
 
>>
>>> +            ret = -EINVAL;
>>> +        else {
>>> +do_resume:
>>> +            d = msecs_to_jiffies(msecs);
>>> +            hoad_resume_jiffies = jiffies + d;
>>> +            cancel_delayed_work_sync(&hoad_resume_work);
>>> +            schedule_delayed_work(&hoad_resume_work, d);
>>
>> It looks like we may use mod_delayed_work(system_wq, ...) here instead of two calls above.
> 
> This will likely get changed to mod_timer()
> 
>>> +    }
>>> +    else if (!strcmp(q, "resume")) {
>>
>> Please, move this "else if" up to the same line with "}" bracket
> 
> Sure - looks like a typo
> 
>>> +        msecs = 0;
>>> +        goto do_resume;
>>> +    } else
>>> +        ret = -EINVAL;
>>
>> In case of you have "{}" brackets in a single branch of if-else, then every if, else if, else
>> branch has to have "{}" brackets even if it's one liner.
> 
> Ok
> 
>>> +    struct kset *kset = kset = kset_create_and_add("hoad", NULL, mm_kobj);
>>
>> 1)kset = kset is here.
>> 2)New line is needed after declaration.
> 
> Ok
> 
>>
>>> +    if (!kset)
>>> +        return -ENOMEM;
>>> +    hoad_kobj = &kset->kobj;
>>> +    hoad_kobj->kset = kset;
>>> +
>>> +    ret = sysfs_create_file(hoad_kobj, &hoad_control_attr.attr);
>>> +    if (ret) {
>>> +        hoad_kobj->kset = NULL;
>>> +        hoad_kobj = NULL;
>>> +        kset_put(kset);
>>> +        return ret;
>>> +    }
>>
>> Why not:
>>
>>     ret = sysfs_create_file(hoad_kobj, &hoad_control_attr.attr);
>>     if (ret) {
>>         kset_put(kset);
>>         return ret;
>>     }
>>
>>     hoad_kobj = &kset->kobj;
>>     hoad_kobj->kset = kset;
> 
> I want to:
> - use sysfs_create_file(hoad_kobj, ...), not sysfs_create_file(&kset->kobj, ...)
> - group configuration together
> 
> 
>> Also, as I see in kernel code, the pair bracket for kset_create_and_add() is kset_unregister().
>> Why we use kset_put() instead?
> 
> Formally, in kset_create_and_add(), sysfs entry gets added and can be opened by other process. So must use refcount-based freeing.



More information about the Devel mailing list