Self-NACK here, because of https://lkml.org/lkml/2018/4/6/724

Sorry for noise.

Vadim

On Fri, Apr 06, 2018 at 07:04:43AM -0700, Vadim Lomovtsev wrote:
> From: Vadim Lomovtsev <vadim.lomovt...@cavium.com>
> 
> It is too expensive to pass u64 values via linked list, instead
> allocate array for them by overall number of mac addresses from netdev.
> 
> This eventually removes multiple kmalloc() calls, aviod memory
> fragmentation and allow to put single null check on kmalloc
> return value in order to prevent a potential null pointer dereference.
> 
> Addresses-Coverity-ID: 1467429 ("Dereference null return value")
> Fixes: 37c3347eb247 ("net: thunderx: add ndo_set_rx_mode callback 
> implementation for VF")
> Reported-by: Dan Carpenter <dan.carpen...@oracle.com>
> Signed-off-by: Vadim Lomovtsev <vadim.lomovt...@cavium.com>
> ---
> Changes from v1 to v2:
>  - C99 syntax: update xcast_addr_list struct field mc[0] -> mc[];
> Changes from v2 to v3:
>  - update commit description with 'Reported-by: Dan Carpenter';
>  - update size calculations for mc list to offsetof() call
>    instead of explicit arithmetic;
> ---
>  drivers/net/ethernet/cavium/thunder/nic.h        |  7 +-----
>  drivers/net/ethernet/cavium/thunder/nicvf_main.c | 28 
> +++++++++---------------
>  2 files changed, 11 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/net/ethernet/cavium/thunder/nic.h 
> b/drivers/net/ethernet/cavium/thunder/nic.h
> index 5fc46c5a4f36..448d1fafc827 100644
> --- a/drivers/net/ethernet/cavium/thunder/nic.h
> +++ b/drivers/net/ethernet/cavium/thunder/nic.h
> @@ -265,14 +265,9 @@ struct nicvf_drv_stats {
>  
>  struct cavium_ptp;
>  
> -struct xcast_addr {
> -     struct list_head list;
> -     u64              addr;
> -};
> -
>  struct xcast_addr_list {
> -     struct list_head list;
>       int              count;
> +     u64              mc[];
>  };
>  
>  struct nicvf_work {
> diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c 
> b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> index 1e9a31fef729..7d9e58533a83 100644
> --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> @@ -1929,7 +1929,7 @@ static void nicvf_set_rx_mode_task(struct work_struct 
> *work_arg)
>                                                 work.work);
>       struct nicvf *nic = container_of(vf_work, struct nicvf, rx_mode_work);
>       union nic_mbx mbx = {};
> -     struct xcast_addr *xaddr, *next;
> +     u8 idx = 0;
>  
>       if (!vf_work)
>               return;
> @@ -1956,16 +1956,10 @@ static void nicvf_set_rx_mode_task(struct work_struct 
> *work_arg)
>       /* check if we have any specific MACs to be added to PF DMAC filter */
>       if (vf_work->mc) {
>               /* now go through kernel list of MACs and add them one by one */
> -             list_for_each_entry_safe(xaddr, next,
> -                                      &vf_work->mc->list, list) {
> +             for (idx = 0; idx < vf_work->mc->count; idx++) {
>                       mbx.xcast.msg = NIC_MBOX_MSG_ADD_MCAST;
> -                     mbx.xcast.data.mac = xaddr->addr;
> +                     mbx.xcast.data.mac = vf_work->mc->mc[idx];
>                       nicvf_send_msg_to_pf(nic, &mbx);
> -
> -                     /* after receiving ACK from PF release memory */
> -                     list_del(&xaddr->list);
> -                     kfree(xaddr);
> -                     vf_work->mc->count--;
>               }
>               kfree(vf_work->mc);
>       }
> @@ -1996,17 +1990,15 @@ static void nicvf_set_rx_mode(struct net_device 
> *netdev)
>                       mode |= BGX_XCAST_MCAST_FILTER;
>                       /* here we need to copy mc addrs */
>                       if (netdev_mc_count(netdev)) {
> -                             struct xcast_addr *xaddr;
> -
> -                             mc_list = kmalloc(sizeof(*mc_list), GFP_ATOMIC);
> -                             INIT_LIST_HEAD(&mc_list->list);
> +                             mc_list = kmalloc(offsetof(typeof(*mc_list),
> +                                                        
> mc[netdev_mc_count(netdev)]),
> +                                               GFP_ATOMIC);
> +                             if (unlikely(!mc_list))
> +                                     return;
> +                             mc_list->count = 0;
>                               netdev_hw_addr_list_for_each(ha, &netdev->mc) {
> -                                     xaddr = kmalloc(sizeof(*xaddr),
> -                                                     GFP_ATOMIC);
> -                                     xaddr->addr =
> +                                     mc_list->mc[mc_list->count] =
>                                               ether_addr_to_u64(ha->addr);
> -                                     list_add_tail(&xaddr->list,
> -                                                   &mc_list->list);
>                                       mc_list->count++;
>                               }
>                       }
> -- 
> 2.14.3
> 

Reply via email to