LCOV - code coverage report
Current view: top level - plugins/dma_intel - main.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 24 157 15.3 %
Date: 2023-07-05 22:20:52 Functions: 8 11 72.7 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: Apache-2.0
       2             :  * Copyright (c) 2022 Cisco Systems, Inc.
       3             :  * Copyright (c) 2022 Intel and/or its affiliates.
       4             :  */
       5             : #include <sys/types.h>
       6             : #include <sys/stat.h>
       7             : #include <fcntl.h>
       8             : #include <vlib/vlib.h>
       9             : #include <vlib/pci/pci.h>
      10             : #include <vlib/dma/dma.h>
      11             : #include <vnet/plugin/plugin.h>
      12             : #include <vpp/app/version.h>
      13             : #include <vppinfra/linux/sysfs.h>
      14             : #include <dma_intel/dsa_intel.h>
      15             : 
      16         559 : VLIB_REGISTER_LOG_CLASS (intel_dsa_log, static) = {
      17             :   .class_name = "intel_dsa",
      18             : };
      19             : 
      20             : intel_dsa_main_t intel_dsa_main;
      21             : 
      22             : void
      23         559 : intel_dsa_assign_channels (vlib_main_t *vm)
      24             : {
      25         559 :   intel_dsa_main_t *idm = &intel_dsa_main;
      26         559 :   intel_dsa_channel_t *ch, **chv = 0;
      27             :   u16 n_threads;
      28             :   int n;
      29             : 
      30         559 :   vec_foreach_index (n, idm->channels)
      31           0 :     vec_append (chv, idm->channels[n]);
      32             : 
      33         559 :   vec_validate (idm->dsa_threads, vlib_get_n_threads () - 1);
      34             : 
      35         559 :   if (vec_len (chv) == 0)
      36             :     {
      37         559 :       dsa_log_debug ("No DSA channels found");
      38         559 :       goto done;
      39             :     }
      40             : 
      41           0 :   if (vec_len (chv) >= vlib_get_n_threads ())
      42           0 :     n_threads = 1;
      43             :   else
      44           0 :     n_threads = vlib_get_n_threads () % vec_len (chv) ?
      45           0 :                         vlib_get_n_threads () / vec_len (chv) + 1 :
      46           0 :                         vlib_get_n_threads () / vec_len (chv);
      47             : 
      48           0 :   for (int i = 0; i < vlib_get_n_threads (); i++)
      49             :     {
      50           0 :       vlib_main_t *tvm = vlib_get_main_by_index (i);
      51           0 :       ch = *vec_elt_at_index (chv, i / n_threads);
      52           0 :       idm->dsa_threads[i].ch = ch;
      53           0 :       ch->n_threads = n_threads;
      54           0 :       dsa_log_debug ("Assigning channel %u/%u to thread %u (numa %u)", ch->did,
      55             :                      ch->qid, i, tvm->numa_node);
      56             :     }
      57             : 
      58           0 : done:
      59             :   /* free */
      60         559 :   vec_free (chv);
      61         559 : }
      62             : 
      63             : static clib_error_t *
      64           0 : intel_dsa_map_region (intel_dsa_channel_t *ch)
      65             : {
      66             :   static clib_error_t *error = NULL;
      67             :   /* map one page */
      68           0 :   uword size = 0x1000;
      69           0 :   uword offset = 0;
      70           0 :   char path[256] = { 0 };
      71             : 
      72           0 :   snprintf (path, sizeof (path), "%s/wq%d.%d", DSA_DEV_PATH, ch->did, ch->qid);
      73           0 :   int fd = open (path, O_RDWR);
      74           0 :   if (fd < 0)
      75           0 :     return clib_error_return (0, "failed to open dsa device %s", path);
      76             : 
      77           0 :   ch->portal =
      78           0 :     clib_mem_vm_map_shared (0, size, fd, offset, "%s", (char *) path);
      79           0 :   if (ch->portal == CLIB_MEM_VM_MAP_FAILED)
      80             :     {
      81           0 :       error = clib_error_return (0, "mmap portal %s failed", path);
      82           0 :       close (fd);
      83           0 :       return error;
      84             :     }
      85             : 
      86           0 :   return NULL;
      87             : }
      88             : 
      89             : static clib_error_t *
      90           0 : intel_dsa_get_info (intel_dsa_channel_t *ch, clib_error_t **error)
      91             : {
      92             :   clib_error_t *err;
      93             :   u8 *tmpstr;
      94           0 :   u8 *dev_dir_name = 0, *wq_dir_name = 0;
      95             : 
      96           0 :   u8 *f = 0;
      97           0 :   dev_dir_name = format (0, "%s/dsa%d", SYS_DSA_PATH, ch->did);
      98             : 
      99           0 :   vec_reset_length (f);
     100           0 :   f = format (f, "%v/numa_node%c", dev_dir_name, 0);
     101           0 :   err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
     102           0 :   if (err)
     103           0 :     goto error;
     104           0 :   ch->numa = atoi ((char *) tmpstr);
     105             : 
     106           0 :   wq_dir_name = format (0, "%s/%U", SYS_DSA_PATH, format_intel_dsa_addr, ch);
     107             : 
     108           0 :   vec_reset_length (f);
     109           0 :   f = format (f, "%v/max_transfer_size%c", wq_dir_name, 0);
     110           0 :   err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
     111           0 :   if (err)
     112           0 :     goto error;
     113           0 :   ch->max_transfer_size = atoi ((char *) tmpstr);
     114             : 
     115           0 :   vec_reset_length (f);
     116           0 :   f = format (f, "%v/max_batch_size%c", wq_dir_name, 0);
     117           0 :   err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
     118           0 :   if (err)
     119           0 :     goto error;
     120           0 :   ch->max_transfers = atoi ((char *) tmpstr);
     121             : 
     122           0 :   vec_reset_length (f);
     123           0 :   f = format (f, "%v/size%c", wq_dir_name, 0);
     124           0 :   err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
     125           0 :   if (err)
     126           0 :     goto error;
     127           0 :   ch->size = atoi ((char *) tmpstr);
     128             : 
     129           0 :   vec_reset_length (f);
     130           0 :   f = format (f, "%v/type%c", wq_dir_name, 0);
     131           0 :   err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
     132           0 :   if (err)
     133           0 :     goto error;
     134           0 :   if (tmpstr)
     135             :     {
     136           0 :       if (!clib_strcmp ((char *) tmpstr, "enabled"))
     137           0 :         ch->type = INTEL_DSA_DEVICE_TYPE_UNKNOWN;
     138           0 :       else if (!clib_strcmp ((char *) tmpstr, "user"))
     139           0 :         ch->type = INTEL_DSA_DEVICE_TYPE_USER;
     140           0 :       else if (!clib_strcmp ((char *) tmpstr, "mdev"))
     141           0 :         ch->type = INTEL_DSA_DEVICE_TYPE_KERNEL;
     142             :       else
     143           0 :         ch->type = INTEL_DSA_DEVICE_TYPE_UNKNOWN;
     144           0 :       vec_free (tmpstr);
     145             :     }
     146             : 
     147           0 :   vec_reset_length (f);
     148           0 :   f = format (f, "%v/state%c", wq_dir_name, 0);
     149           0 :   err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
     150           0 :   if (err)
     151           0 :     goto error;
     152           0 :   if (tmpstr)
     153             :     {
     154           0 :       if (!clib_strcmp ((char *) tmpstr, "enabled"))
     155           0 :         ch->state = 1;
     156             :       else
     157           0 :         ch->state = 0;
     158           0 :       vec_free (tmpstr);
     159             :     }
     160             : 
     161           0 :   vec_reset_length (f);
     162           0 :   f = format (f, "%v/ats_disable%c", wq_dir_name, 0);
     163           0 :   err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
     164           0 :   if (err)
     165           0 :     goto error;
     166           0 :   ch->ats_disable = atoi ((char *) tmpstr);
     167             : 
     168           0 :   vec_reset_length (f);
     169           0 :   f = format (f, "%v/block_on_fault%c", wq_dir_name, 0);
     170           0 :   err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
     171           0 :   if (err)
     172           0 :     goto error;
     173           0 :   ch->block_on_fault = atoi ((char *) tmpstr);
     174             : 
     175           0 :   vec_reset_length (f);
     176           0 :   f = format (f, "%v/mode%c", wq_dir_name, 0);
     177           0 :   err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
     178           0 :   if (err)
     179           0 :     goto error;
     180           0 :   if (tmpstr)
     181             :     {
     182           0 :       if (!clib_strcmp ((char *) tmpstr, "dedicated"))
     183           0 :         ch->mode = 1;
     184             :       else
     185           0 :         ch->mode = 0;
     186           0 :       vec_free (tmpstr);
     187             :     }
     188             : 
     189           0 :   vec_free (f);
     190           0 :   vec_free (dev_dir_name);
     191           0 :   vec_free (wq_dir_name);
     192           0 :   return NULL;
     193             : 
     194           0 : error:
     195           0 :   vec_free (f);
     196           0 :   vec_free (dev_dir_name);
     197           0 :   vec_free (wq_dir_name);
     198             : 
     199           0 :   return err;
     200             : }
     201             : 
     202             : clib_error_t *
     203           0 : intel_dsa_add_channel (vlib_main_t *vm, intel_dsa_channel_t *ch)
     204             : {
     205           0 :   intel_dsa_main_t *dm = &intel_dsa_main;
     206           0 :   clib_error_t *err = 0;
     207             : 
     208           0 :   if (intel_dsa_map_region (ch))
     209           0 :     return clib_error_return (0, "dsa open device failed");
     210             : 
     211           0 :   if (intel_dsa_get_info (ch, &err))
     212           0 :     return clib_error_return (err, "dsa info not scanned");
     213             : 
     214           0 :   vec_validate (dm->channels, ch->numa);
     215           0 :   vec_add1 (dm->channels[ch->numa], ch);
     216             : 
     217           0 :   return err;
     218             : }
     219             : 
     220             : static clib_error_t *
     221         559 : dsa_config (vlib_main_t *vm, unformat_input_t *input)
     222             : {
     223         559 :   clib_error_t *error = 0;
     224             :   intel_dsa_channel_t *ch;
     225             :   u32 did, qid;
     226             : 
     227         559 :   if (intel_dsa_main.lock == 0)
     228         559 :     clib_spinlock_init (&(intel_dsa_main.lock));
     229             : 
     230         559 :   if ((error = vlib_dma_register_backend (vm, &intel_dsa_backend)))
     231           0 :     goto done;
     232             : 
     233         559 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     234             :     {
     235           0 :       if (unformat (input, "dev wq%d.%d", &did, &qid))
     236             :         {
     237           0 :           ch = clib_mem_alloc_aligned (sizeof (*ch), CLIB_CACHE_LINE_BYTES);
     238           0 :           clib_memset (ch, 0, sizeof (*ch));
     239           0 :           ch->did = did;
     240           0 :           ch->qid = qid;
     241           0 :           if (intel_dsa_add_channel (vm, ch))
     242           0 :             clib_mem_free (ch);
     243             :         }
     244           0 :       else if (unformat_skip_white_space (input))
     245             :         ;
     246             :       else
     247             :         {
     248           0 :           error = clib_error_return (0, "unknown input `%U'",
     249             :                                      format_unformat_error, input);
     250           0 :           goto done;
     251             :         }
     252             :     }
     253             : 
     254         559 : done:
     255         559 :   return error;
     256             : }
     257             : 
     258        5066 : VLIB_CONFIG_FUNCTION (dsa_config, "dsa");
     259             : 
     260             : clib_error_t *
     261         559 : intel_dsa_num_workers_change (vlib_main_t *vm)
     262             : {
     263         559 :   intel_dsa_assign_channels (vm);
     264         559 :   return 0;
     265             : }
     266             : 
     267        1119 : VLIB_NUM_WORKERS_CHANGE_FN (intel_dsa_num_workers_change);
     268             : 
     269             : VLIB_PLUGIN_REGISTER () = {
     270             :   .version = VPP_BUILD_VER,
     271             :   .description = "Intel DSA Backend",
     272             : };

Generated by: LCOV version 1.14