Line data Source code
1 : /* SPDX-License-Identifier: Apache-2.0
2 : * Copyright (c) 2022 Cisco Systems, Inc.
3 : */
4 :
5 : #include <vlib/vlib.h>
6 : #include <vlib/physmem_funcs.h>
7 : #include <vlib/dma/dma.h>
8 :
9 : static clib_error_t *
10 0 : show_dma_backends_command_fn (vlib_main_t *vm, unformat_input_t *input,
11 : vlib_cli_command_t *cmd)
12 : {
13 0 : vlib_dma_main_t *dm = &vlib_dma_main;
14 :
15 0 : if (vec_len (dm->backends))
16 0 : {
17 : vlib_dma_backend_t *b;
18 0 : vec_foreach (b, dm->backends)
19 0 : vlib_cli_output (vm, "%s", b->name);
20 : }
21 : else
22 0 : vlib_cli_output (vm, "No active DMA backends");
23 :
24 0 : return 0;
25 : }
26 :
27 285289 : VLIB_CLI_COMMAND (avf_create_command, static) = {
28 : .path = "show dma backends",
29 : .short_help = "show dma backends",
30 : .function = show_dma_backends_command_fn,
31 : };
32 :
33 : static void
34 0 : test_dma_cb_fn (vlib_main_t *vm, vlib_dma_batch_t *b)
35 : {
36 0 : fformat (stderr, "%s: cb %p cookie %lx\n", __func__, b,
37 : vlib_dma_batch_get_cookie (vm, b));
38 0 : }
39 :
40 : static clib_error_t *
41 0 : fill_random_data (void *buffer, uword size)
42 : {
43 0 : uword seed = random_default_seed ();
44 :
45 0 : uword remain = size;
46 0 : const uword p = clib_mem_get_page_size ();
47 0 : uword offset = 0;
48 :
49 : clib_random_buffer_t rb;
50 0 : clib_random_buffer_init (&rb, seed);
51 :
52 0 : while (remain > 0)
53 : {
54 0 : uword fill_size = clib_min (p, remain);
55 :
56 0 : clib_random_buffer_fill (&rb, fill_size);
57 0 : void *rbuf = clib_random_buffer_get_data (&rb, fill_size);
58 0 : clib_memcpy_fast (buffer + offset, rbuf, fill_size);
59 0 : clib_random_buffer_free (&rb);
60 :
61 0 : offset += fill_size;
62 0 : remain -= fill_size;
63 : }
64 :
65 0 : return 0;
66 : }
67 :
68 : static clib_error_t *
69 0 : test_dma_command_fn (vlib_main_t *vm, unformat_input_t *input,
70 : vlib_cli_command_t *cmd)
71 : {
72 0 : clib_error_t *err = 0;
73 : vlib_dma_batch_t *b;
74 0 : int config_index = -1;
75 : u32 rsz, n_alloc, v;
76 0 : u8 *from = 0, *to = 0;
77 0 : vlib_dma_config_t cfg = { .max_transfers = 256,
78 : .max_transfer_size = 4096,
79 : .callback_fn = test_dma_cb_fn };
80 :
81 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
82 : {
83 0 : if (unformat (input, "transfers %u", &v))
84 0 : cfg.max_transfers = v;
85 0 : else if (unformat (input, "size %u", &v))
86 0 : cfg.max_transfer_size = v;
87 : else
88 0 : return clib_error_return (0, "unknown input `%U'",
89 : format_unformat_error, input);
90 : }
91 :
92 0 : if ((config_index = vlib_dma_config_add (vm, &cfg)) < 0)
93 : {
94 0 : err = clib_error_return (0, "Unable to allocate dma config");
95 0 : return err;
96 : }
97 :
98 0 : rsz = round_pow2 (cfg.max_transfer_size, CLIB_CACHE_LINE_BYTES);
99 0 : n_alloc = rsz * cfg.max_transfers * 2;
100 :
101 0 : if ((from = vlib_physmem_alloc_aligned_on_numa (
102 : vm, n_alloc, CLIB_CACHE_LINE_BYTES, vm->numa_node)) == 0)
103 : {
104 0 : err = clib_error_return (0, "Unable to allocate %u bytes of physmem",
105 : n_alloc);
106 0 : return err;
107 : }
108 0 : to = from + n_alloc / 2;
109 :
110 : u32 port_allocator_seed;
111 :
112 0 : fill_random_data (from, (uword) cfg.max_transfers * rsz);
113 :
114 0 : b = vlib_dma_batch_new (vm, config_index);
115 0 : vlib_dma_batch_set_cookie (vm, b, 0x12345678);
116 :
117 0 : port_allocator_seed = clib_cpu_time_now ();
118 0 : int transfers = random_u32 (&port_allocator_seed) % cfg.max_transfers;
119 0 : if (!transfers)
120 0 : transfers = 1;
121 0 : for (int i = 0; i < transfers; i++)
122 0 : vlib_dma_batch_add (vm, b, to + i * rsz, from + i * rsz,
123 : cfg.max_transfer_size);
124 :
125 0 : vlib_dma_batch_submit (vm, b);
126 0 : return err;
127 : }
128 :
129 : static clib_error_t *
130 0 : test_show_dma_fn (vlib_main_t *vm, unformat_input_t *input,
131 : vlib_cli_command_t *cmd)
132 : {
133 0 : clib_error_t *err = 0;
134 0 : int config_index = 0;
135 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
136 : {
137 0 : if (unformat (input, "config %u", &config_index))
138 : ;
139 : else
140 0 : return clib_error_return (0, "unknown input `%U'",
141 : format_unformat_error, input);
142 : }
143 :
144 0 : for (u32 i = 0; i < vlib_get_n_threads (); i++)
145 0 : vlib_cli_output (vm, "Config %d %U", config_index, vlib_dma_config_info,
146 : config_index, vlib_get_main_by_index (i));
147 0 : return err;
148 : }
149 :
150 285289 : VLIB_CLI_COMMAND (test_dma_command, static) = {
151 : .path = "test dma",
152 : .short_help = "test dma [transfers <x> size <x>]",
153 : .function = test_dma_command_fn,
154 : };
155 :
156 285289 : VLIB_CLI_COMMAND (show_dma_command, static) = {
157 : .path = "show dma",
158 : .short_help = "show dma [config <x>]",
159 : .function = test_show_dma_fn,
160 : };
|