LCOV - code coverage report
Current view: top level - drivers/net/mlx4 - mlx4_utils.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 37 0.0 %
Date: 2025-02-01 18:54:23 Functions: 0 6 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 24 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2017 6WIND S.A.
       3                 :            :  * Copyright 2017 Mellanox Technologies, Ltd
       4                 :            :  */
       5                 :            : 
       6                 :            : /**
       7                 :            :  * @file
       8                 :            :  * Utility functions used by the mlx4 driver.
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <errno.h>
      12                 :            : #include <fcntl.h>
      13                 :            : #include <stddef.h>
      14                 :            : #include <stdint.h>
      15                 :            : 
      16                 :            : #include <rte_errno.h>
      17                 :            : #include <rte_malloc.h>
      18                 :            : #include <rte_memory.h>
      19                 :            : 
      20                 :            : #include "mlx4_utils.h"
      21                 :            : 
      22                 :            : /**
      23                 :            :  * Make a file descriptor non-blocking.
      24                 :            :  *
      25                 :            :  * @param fd
      26                 :            :  *   File descriptor to alter.
      27                 :            :  *
      28                 :            :  * @return
      29                 :            :  *   0 on success, negative errno value otherwise and rte_errno is set.
      30                 :            :  */
      31                 :            : int
      32                 :          0 : mlx4_fd_set_non_blocking(int fd)
      33                 :            : {
      34                 :          0 :         int ret = fcntl(fd, F_GETFL);
      35                 :            : 
      36   [ #  #  #  # ]:          0 :         if (ret != -1 && !fcntl(fd, F_SETFL, ret | O_NONBLOCK))
      37                 :            :                 return 0;
      38                 :            :         MLX4_ASSERT(errno);
      39                 :          0 :         rte_errno = errno;
      40                 :          0 :         return -rte_errno;
      41                 :            : }
      42                 :            : 
      43                 :            : /**
      44                 :            :  * Internal helper to allocate memory once for several disparate objects.
      45                 :            :  *
      46                 :            :  * The most restrictive alignment constraint for standard objects is assumed
      47                 :            :  * to be sizeof(double) and is used as a default value.
      48                 :            :  *
      49                 :            :  * C11 code would include stdalign.h and use alignof(max_align_t) however
      50                 :            :  * we'll stick with C99 for the time being.
      51                 :            :  */
      52                 :            : static inline size_t
      53                 :          0 : mlx4_mallocv_inline(const char *type, const struct mlx4_malloc_vec *vec,
      54                 :            :                     unsigned int cnt, int zero, int socket)
      55                 :            : {
      56                 :            :         unsigned int i;
      57                 :            :         size_t size;
      58                 :            :         size_t least;
      59                 :            :         uint8_t *data = NULL;
      60                 :          0 :         int fill = !vec[0].addr;
      61                 :            : 
      62                 :          0 : fill:
      63                 :            :         size = 0;
      64                 :            :         least = 0;
      65         [ #  # ]:          0 :         for (i = 0; i < cnt; ++i) {
      66                 :          0 :                 size_t align = (uintptr_t)vec[i].align;
      67                 :            : 
      68         [ #  # ]:          0 :                 if (!align) {
      69                 :            :                         align = sizeof(double);
      70         [ #  # ]:          0 :                 } else if (!rte_is_power_of_2(align)) {
      71                 :          0 :                         rte_errno = EINVAL;
      72                 :          0 :                         goto error;
      73                 :            :                 }
      74                 :            :                 if (least < align)
      75                 :            :                         least = align;
      76                 :          0 :                 align = RTE_ALIGN_CEIL(size, align);
      77                 :          0 :                 size = align + vec[i].size;
      78   [ #  #  #  # ]:          0 :                 if (fill && vec[i].addr)
      79                 :          0 :                         *vec[i].addr = data + align;
      80                 :            :         }
      81         [ #  # ]:          0 :         if (fill)
      82                 :          0 :                 return size;
      83         [ #  # ]:          0 :         if (!zero)
      84                 :          0 :                 data = rte_malloc_socket(type, size, least, socket);
      85                 :            :         else
      86                 :          0 :                 data = rte_zmalloc_socket(type, size, least, socket);
      87         [ #  # ]:          0 :         if (data) {
      88                 :            :                 fill = 1;
      89                 :          0 :                 goto fill;
      90                 :            :         }
      91                 :          0 :         rte_errno = ENOMEM;
      92                 :            : error:
      93         [ #  # ]:          0 :         for (i = 0; i != cnt; ++i)
      94         [ #  # ]:          0 :                 if (vec[i].addr)
      95                 :          0 :                         *vec[i].addr = NULL;
      96                 :            :         return 0;
      97                 :            : }
      98                 :            : 
      99                 :            : /**
     100                 :            :  * Allocate memory once for several disparate objects.
     101                 :            :  *
     102                 :            :  * This function adds iovec-like semantics (e.g. readv()) to rte_malloc().
     103                 :            :  * Memory is allocated once for several contiguous objects of nonuniform
     104                 :            :  * sizes and alignment constraints.
     105                 :            :  *
     106                 :            :  * Each entry of @p vec describes the size, alignment constraint and
     107                 :            :  * provides a buffer address where the resulting object pointer must be
     108                 :            :  * stored.
     109                 :            :  *
     110                 :            :  * The buffer of the first entry is guaranteed to point to the beginning of
     111                 :            :  * the allocated region and is safe to use with rte_free().
     112                 :            :  *
     113                 :            :  * NULL buffers are silently ignored.
     114                 :            :  *
     115                 :            :  * Providing a NULL buffer in the first entry prevents this function from
     116                 :            :  * allocating any memory but has otherwise no effect on its behavior. In
     117                 :            :  * this case, the contents of remaining non-NULL buffers are updated with
     118                 :            :  * addresses relative to zero (i.e. offsets that would have been used during
     119                 :            :  * the allocation).
     120                 :            :  *
     121                 :            :  * @param[in] type
     122                 :            :  *   A string identifying the type of allocated objects (useful for debug
     123                 :            :  *   purposes, such as identifying the cause of a memory leak). Can be NULL.
     124                 :            :  * @param[in, out] vec
     125                 :            :  *   Description of objects to allocate memory for.
     126                 :            :  * @param cnt
     127                 :            :  *   Number of entries in @p vec.
     128                 :            :  *
     129                 :            :  * @return
     130                 :            :  *   Size in bytes of the allocated region including any padding. In case of
     131                 :            :  *   error, rte_errno is set, 0 is returned and NULL is stored in the
     132                 :            :  *   non-NULL buffers pointed by @p vec.
     133                 :            :  *
     134                 :            :  * @see struct mlx4_malloc_vec
     135                 :            :  * @see rte_malloc()
     136                 :            :  */
     137                 :            : size_t
     138                 :          0 : mlx4_mallocv(const char *type, const struct mlx4_malloc_vec *vec,
     139                 :            :              unsigned int cnt)
     140                 :            : {
     141                 :          0 :         return mlx4_mallocv_inline(type, vec, cnt, 0, SOCKET_ID_ANY);
     142                 :            : }
     143                 :            : 
     144                 :            : /**
     145                 :            :  * Combines the semantics of mlx4_mallocv() with those of rte_zmalloc().
     146                 :            :  *
     147                 :            :  * @see mlx4_mallocv()
     148                 :            :  * @see rte_zmalloc()
     149                 :            :  */
     150                 :            : size_t
     151                 :          0 : mlx4_zmallocv(const char *type, const struct mlx4_malloc_vec *vec,
     152                 :            :               unsigned int cnt)
     153                 :            : {
     154                 :          0 :         return mlx4_mallocv_inline(type, vec, cnt, 1, SOCKET_ID_ANY);
     155                 :            : }
     156                 :            : 
     157                 :            : /**
     158                 :            :  * Socket-aware version of mlx4_mallocv().
     159                 :            :  *
     160                 :            :  * This function takes one additional parameter.
     161                 :            :  *
     162                 :            :  * @param socket
     163                 :            :  *   NUMA socket to allocate memory on. If SOCKET_ID_ANY is used, this
     164                 :            :  *   function will behave the same as mlx4_mallocv().
     165                 :            :  *
     166                 :            :  * @see mlx4_mallocv()
     167                 :            :  * @see rte_malloc_socket()
     168                 :            :  */
     169                 :            : size_t
     170                 :          0 : mlx4_mallocv_socket(const char *type, const struct mlx4_malloc_vec *vec,
     171                 :            :                     unsigned int cnt, int socket)
     172                 :            : {
     173                 :          0 :         return mlx4_mallocv_inline(type, vec, cnt, 0, socket);
     174                 :            : }
     175                 :            : 
     176                 :            : /**
     177                 :            :  * Combines the semantics of mlx4_mallocv_socket() with those of
     178                 :            :  * mlx4_zmalloc_socket().
     179                 :            :  *
     180                 :            :  * @see mlx4_mallocv_socket()
     181                 :            :  * @see rte_zmalloc_socket()
     182                 :            :  */
     183                 :            : size_t
     184                 :          0 : mlx4_zmallocv_socket(const char *type, const struct mlx4_malloc_vec *vec,
     185                 :            :                      unsigned int cnt, int socket)
     186                 :            : {
     187                 :          0 :         return mlx4_mallocv_inline(type, vec, cnt, 1, socket);
     188                 :            : }

Generated by: LCOV version 1.14