[Intel-wired-lan] [PATCH net-next] idpf: Slightly simplify memory management in idpf_add_del_mac_filters()

Christophe JAILLET christophe.jaillet at wanadoo.fr
Mon Aug 26 17:14:55 UTC 2024


Le 26/08/2024 à 11:15, Przemek Kitszel a écrit :
> On 8/23/24 11:10, Dan Carpenter wrote:
>> On Fri, Aug 23, 2024 at 08:23:29AM +0200, Christophe JAILLET wrote:
>>> In idpf_add_del_mac_filters(), filters are chunked up into multiple
>>> messages to avoid sending a control queue message buffer that is too 
>>> large.
>>>
>>> Each chunk has up to IDPF_NUM_FILTERS_PER_MSG entries. So except for the
>>> last iteration which can be smaller, space for exactly
>>> IDPF_NUM_FILTERS_PER_MSG entries is allocated.
>>>
>>> There is no need to free and reallocate a smaller array just for the 
>>> last
>>> iteration.
>>>
>>> This slightly simplifies the code and avoid an (unlikely) memory 
>>> allocation
>>> failure.
>>>
> 
> Thanks, that is indeed an improvement.
> 
>>> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
>>> ---
>>>   drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 7 +++++--
>>>   1 file changed, 5 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c 
>>> b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
>>> index 70986e12da28..b6f4b58e1094 100644
>>> --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
>>> +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
>>> @@ -3669,12 +3669,15 @@ int idpf_add_del_mac_filters(struct 
>>> idpf_vport *vport,
>>>           entries_size = sizeof(struct virtchnl2_mac_addr) * 
>>> num_entries;
>>>           buf_size = struct_size(ma_list, mac_addr_list, num_entries);
>>> -        if (!ma_list || num_entries != IDPF_NUM_FILTERS_PER_MSG) {
>>> -            kfree(ma_list);
>>> +        if (!ma_list) {
>>>               ma_list = kzalloc(buf_size, GFP_ATOMIC);
>>>               if (!ma_list)
>>>                   return -ENOMEM;
>>>           } else {
>>> +            /* ma_list was allocated in the first iteration
>>> +             * so IDPF_NUM_FILTERS_PER_MSG entries are
>>> +             * available
>>> +             */
>>>               memset(ma_list, 0, buf_size);
>>>           }
>>
>> It would be even nicer to move the ma_list allocation outside the loop:
>>
>>          buf_size = struct_size(ma_list, mac_addr_list, 
>> IDPF_NUM_FILTERS_PER_MSG);
>>          ma_list = kmalloc(buf_size, GFP_ATOMIC);
> 
> good point
> 
> I've opened whole function for inspection and it asks for even more,
> as of now, we allocate an array in atomic context, just to have a copy
> of some stuff from the spinlock-protected list.
> 
> It would be good to have allocation as pointed by Dan prior to iteration
> and fill it on the fly, sending when new message would not fit plus once
> at the end. Sending procedure is safe to be called under a spinlock.

If I understand correctly, you propose to remove the initial copy in 
mac_addr and hold &vport_config->mac_filter_list_lock till the end of 
the function?

That's it?

There is a wait_for_completion_timeout() in idpf_vc_xn_exec() and the 
default time-out is IDPF_VC_XN_DEFAULT_TIMEOUT_MSEC	(60 * 1000)

So, should an issue occurs, and the time out run till the end, we could 
hold the 'mac_filter_list_lock' spinlock for up to 60 seconds?
Is that ok?


And if in asynch update mode, idpf_mac_filter_async_handler() also takes 
&vport_config->mac_filter_list_lock;. Could we dead-lock?


So, I'm not sure to understand what you propose, or the code in 
idpf_add_del_mac_filters() and co.

> 
> CCing author; CCing Olek to ask if there are already some refactors that
> would conflict with this.

I'll way a few days for these feedbacks and send a v2.

CJ

> 
>>
>> regards,
>> dan carpenter
>>
> 
> 
> 



More information about the Intel-wired-lan mailing list