aboutsummaryrefslogtreecommitdiffstats
path: root/perftool/new.cpel
AgeCommit message (Expand)AuthorFilesLines
2016-02-12Performance tools, initial check-inDave Barach1-0/+0
='n50' href='#n50'>50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
/* SPDX-License-Identifier: Apache-2.0
 * Copyright (c) 2022 Cisco Systems, Inc.
 */

#include <vlib/vlib.h>
#include <vlib/physmem_funcs.h>
#include <vlib/dma/dma.h>

static clib_error_t *
show_dma_backends_command_fn (vlib_main_t *vm, unformat_input_t *input,
			      vlib_cli_command_t *cmd)
{
  vlib_dma_main_t *dm = &vlib_dma_main;

  if (vec_len (dm->backends))
    {
      vlib_dma_backend_t *b;
      vec_foreach (b, dm->backends)
	vlib_cli_output (vm, "%s", b->name);
    }
  else
    vlib_cli_output (vm, "No active DMA backends");

  return 0;
}

VLIB_CLI_COMMAND (avf_create_command, static) = {
  .path = "show dma backends",
  .short_help = "show dma backends",
  .function = show_dma_backends_command_fn,
};

static void
test_dma_cb_fn (vlib_main_t *vm, vlib_dma_batch_t *b)
{
  fformat (stderr, "%s: cb %p cookie %lx\n", __func__, b,
	   vlib_dma_batch_get_cookie (vm, b));
}

static clib_error_t *
fill_random_data (void *buffer, uword size)
{
  uword seed = random_default_seed ();

  uword remain = size;
  const uword p = clib_mem_get_page_size ();
  uword offset = 0;

  clib_random_buffer_t rb;
  clib_random_buffer_init (&rb, seed);

  while (remain > 0)
    {
      uword fill_size = clib_min (p, remain);

      clib_random_buffer_fill (&rb, fill_size);
      void *rbuf = clib_random_buffer_get_data (&rb, fill_size);
      clib_memcpy_fast (buffer + offset, rbuf, fill_size);
      clib_random_buffer_free (&rb);

      offset += fill_size;
      remain -= fill_size;
    }

  return 0;
}

static clib_error_t *
test_dma_command_fn (vlib_main_t *vm, unformat_input_t *input,
		     vlib_cli_command_t *cmd)
{
  clib_error_t *err = 0;
  vlib_dma_batch_t *b;
  int config_index = -1;
  u32 rsz, n_alloc, v;
  u8 *from = 0, *to = 0;
  vlib_dma_config_t cfg = { .max_transfers = 256,
			    .max_transfer_size = 4096,
			    .callback_fn = test_dma_cb_fn };

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "transfers %u", &v))
	cfg.max_transfers = v;
      else if (unformat (input, "size %u", &v))
	cfg.max_transfer_size = v;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if ((config_index = vlib_dma_config_add (vm, &cfg)) < 0)
    {
      err = clib_error_return (0, "Unable to allocate dma config");
      return err;
    }

  rsz = round_pow2 (cfg.max_transfer_size, CLIB_CACHE_LINE_BYTES);
  n_alloc = rsz * cfg.max_transfers * 2;

  if ((from = vlib_physmem_alloc_aligned_on_numa (
	 vm, n_alloc, CLIB_CACHE_LINE_BYTES, vm->numa_node)) == 0)
    {
      err = clib_error_return (0, "Unable to allocate %u bytes of physmem",
			       n_alloc);
      return err;
    }
  to = from + n_alloc / 2;

  u32 port_allocator_seed;

  fill_random_data (from, cfg.max_transfers * rsz);

  b = vlib_dma_batch_new (vm, config_index);
  vlib_dma_batch_set_cookie (vm, b, 0x12345678);

  port_allocator_seed = clib_cpu_time_now ();
  int transfers = random_u32 (&port_allocator_seed) % cfg.max_transfers;
  if (!transfers)
    transfers = 1;
  for (int i = 0; i < transfers; i++)
    vlib_dma_batch_add (vm, b, to + i * rsz, from + i * rsz,
			cfg.max_transfer_size);

  vlib_dma_batch_submit (vm, b);
  return err;
}

static clib_error_t *
test_show_dma_fn (vlib_main_t *vm, unformat_input_t *input,
		  vlib_cli_command_t *cmd)
{
  clib_error_t *err = 0;
  int config_index = 0;
  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "config %u", &config_index))
	;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  for (u32 i = 0; i < vlib_get_n_threads (); i++)
    vlib_cli_output (vm, "Config %d %U", config_index, vlib_dma_config_info,
		     config_index, vlib_get_main_by_index (i));
  return err;
}

VLIB_CLI_COMMAND (test_dma_command, static) = {
  .path = "test dma",
  .short_help = "test dma [transfers <x> size <x>]",
  .function = test_dma_command_fn,
};

VLIB_CLI_COMMAND (show_dma_command, static) = {
  .path = "show dma",
  .short_help = "show dma [config <x>]",
  .function = test_show_dma_fn,
};