On 2023/7/5 14:29, Eugenio Perez Martin wrote:
> On Wed, Jul 5, 2023 at 3:43 AM Hawkins Jiawei <yin31...@gmail.com> wrote:
>>
>> On 2023/7/4 22:53, Eugenio Perez Martin wrote:
>>> On Thu, Jun 29, 2023 at 5:26 PM Hawkins Jiawei <yin31...@gmail.com> wrote:
>>>>
>>>> This patch refactors vhost_vdpa_net_load_mac() to
>>>> restore the MAC address filtering state at device's startup.
>>>>
>>>> Signed-off-by: Hawkins Jiawei <yin31...@gmail.com>
>>>> ---
>>>> v2:
>>>>     - use iovec suggested by Eugenio
>>>>     - avoid sending CVQ command in default state
>>>>
>>>> v1: 
>>>> https://lore.kernel.org/all/00f72fe154a882fd6dc15bc39e3a1ac63f9dadce.1687402580.git.yin31...@gmail.com/
>>>>
>>>>    net/vhost-vdpa.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>    1 file changed, 51 insertions(+)
>>>>
>>>> diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
>>>> index 0bd1c7817c..cb45c84c88 100644
>>>> --- a/net/vhost-vdpa.c
>>>> +++ b/net/vhost-vdpa.c
>>>> @@ -665,6 +665,57 @@ static int vhost_vdpa_net_load_mac(VhostVDPAState *s, 
>>>> const VirtIONet *n)
>>>>            }
>>>>        }
>>>>
>>>> +    if (virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_CTRL_RX)) {
>>>> +        if (n->mac_table.in_use != 0) {
>>>
>>> This may be just style nitpicking, but I find it more clear to return
>>> early if conditions are not met and then send the CVQ command.
>>
>> Yes, this makes code more clear to read.
>>
>> But it appears that we may meet a problem if the function
>> vhost_vdpa_net_load_x() sends multiple CVQ commands. It is possible that
>> we might not meet the condition for one of the CVQ commands, but we
>> could still meet the conditions for other CVQ commands.
>>
>> Therefore, in the case of vhost_vdpa_net_load_x() sending multiple CVQ
>> commands, if we still hope to use this style, should we split the
>> function into multiple functions, with each function responsible for
>> sending only one CVQ command? Or should we jump to the next CVQ command
>> instead of returning from the function if the conditions are not met?
>>
>
> In that case I'd suggest using multiples if() {}, as each ctrl command
> processing code is very small.
>
> But for VIRTIO_NET_F_CTRL_RX particular case your patch propose:
> if (x) {
>    if (y) {
>      ...
>    }
> }
>
> So in my opinion it makes sense to convert to:
> if (!x || !y) {
>    return;
> }
> ...

Thanks for your explanation.

I will refactor the patch according to your suggestion.

Thanks!


>
> We can always change later if needed.
>
> Thanks!
>
>> Thanks!
>>
>>
>>> Something like:
>>> /*
>>>    * According to ...
>>>    */
>>> if (!virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_CTRL_RX)) ||
>>> (n->mac_table.in_use == 0)) {
>>>     return 0
>>> }
>>>
>>> uni_entries = n->mac_table.first_multi,
>>> ...
>>> ---
>>>
>>> Now I just realized vhost_vdpa_net_load_mac does not follow this for
>>> checking VIRTIO_NET_F_CTRL_MAC_ADDR.
>>>
>>> I'm ok if you leave it this way though.
>>>
>>> Thanks!
>>>
>>>> +            /*
>>>> +             * According to virtio_net_reset(), device uses an empty MAC 
>>>> filter
>>>> +             * table as its default state.
>>>> +             *
>>>> +             * Therefore, there is no need to send this CVQ command if the
>>>> +             * driver also sets an empty MAC filter table, which aligns 
>>>> with
>>>> +             * the device's defaults.
>>>> +             *
>>>> +             * Note that the device's defaults can mismatch the driver's
>>>> +             * configuration only at live migration.
>>>> +             */
>>>> +            uint32_t uni_entries = n->mac_table.first_multi,
>>>> +                     uni_macs_size = uni_entries * ETH_ALEN,
>>>> +                     mul_entries = n->mac_table.in_use - uni_entries,
>>>> +                     mul_macs_size = mul_entries * ETH_ALEN;
>>>> +            struct virtio_net_ctrl_mac uni = {
>>>> +                .entries = cpu_to_le32(uni_entries),
>>>> +            };
>>>> +            struct virtio_net_ctrl_mac mul = {
>>>> +                .entries = cpu_to_le32(mul_entries),
>>>> +            };
>>>> +            const struct iovec data[] = {
>>>> +                {
>>>> +                    .iov_base = &uni,
>>>> +                    .iov_len = sizeof(uni),
>>>> +                }, {
>>>> +                    .iov_base = n->mac_table.macs,
>>>> +                    .iov_len = uni_macs_size,
>>>> +                }, {
>>>> +                    .iov_base = &mul,
>>>> +                    .iov_len = sizeof(mul),
>>>> +                }, {
>>>> +                    .iov_base = &n->mac_table.macs[uni_macs_size],
>>>> +                    .iov_len = mul_macs_size,
>>>> +                },
>>>> +            };
>>>> +            ssize_t dev_written = vhost_vdpa_net_load_cmd(s,
>>>> +                                        VIRTIO_NET_CTRL_MAC,
>>>> +                                        VIRTIO_NET_CTRL_MAC_TABLE_SET,
>>>> +                                        data, ARRAY_SIZE(data));
>>>> +            if (unlikely(dev_written < 0)) {
>>>> +                return dev_written;
>>>> +            }
>>>> +            if (*s->status != VIRTIO_NET_OK) {
>>>> +                return -EINVAL;
>>>> +            }
>>>> +        }
>>>> +    }
>>>> +
>>>>        return 0;
>>>>    }
>>>>
>>>> --
>>>> 2.25.1
>>>>
>>>
>>
>

Reply via email to