summaryrefslogtreecommitdiffstats
path: root/src/svm/svm_fifo_segment.h
blob: 1872da169f9180c461486ee9c0d1ea3193f21893 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
/*
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __included_ssvm_fifo_segment_h__
#define __included_ssvm_fifo_segment_h__

#include <svm/ssvm.h>
#include <svm/svm_fifo.h>
#include <vppinfra/lock.h>

typedef enum
{
  FIFO_SEGMENT_FREELIST_NONE = -1,
  FIFO_SEGMENT_RX_FREELIST = 0,
  FIFO_SEGMENT_TX_FREELIST,
  FIFO_SEGMENT_N_FREELISTS
} svm_fifo_segment_freelist_t;

#define FIFO_SEGMENT_MIN_FIFO_SIZE 4096
#define FIFO_SEGMENT_MAX_FIFO_SIZE (8<<20)	/* 8mb max fifo size */
#define FIFO_SEGMENT_ALLOC_CHUNK_SIZE 32	/* Allocation quantum */

#define FIFO_SEGMENT_F_IS_PREALLOCATED	(1 << 0)
#define FIFO_SEGMENT_F_WILL_DELETE	(1 << 1)

typedef struct
{
  svm_fifo_t *fifos;		/**< Linked list of active RX fifos */
  svm_fifo_t **free_fifos;	/**< Freelists, by fifo size  */
  u32 n_active_fifos;		/**< Number of active fifos */
  u8 flags;			/**< Segment flags */
} svm_fifo_segment_header_t;

typedef struct
{
  ssvm_private_t ssvm;
  svm_fifo_segment_header_t *h;
} svm_fifo_segment_private_t;

typedef struct
{
  volatile u32 lock;

  /** pool of segments */
  svm_fifo_segment_private_t *segments;
  /* Where to put the next one */
  u64 next_baseva;
  u32 timeout_in_seconds;
} svm_fifo_segment_main_t;

extern svm_fifo_segment_main_t svm_fifo_segment_main;

typedef struct
{
  ssvm_segment_type_t segment_type;
  char *segment_name;
  u32 segment_size;
  u32 *new_segment_indices;
  int memfd_fd;
} svm_fifo_segment_create_args_t;

#define svm_fifo_segment_flags(_seg) _seg->h->flags

static inline svm_fifo_segment_private_t *
svm_fifo_segment_get_segment (u32 segment_index)
{
  svm_fifo_segment_main_t *ssm = &svm_fifo_segment_main;
  return pool_elt_at_index (ssm->segments, segment_index);
}

static inline u8
svm_fifo_segment_has_fifos (svm_fifo_segment_private_t * fifo_segment)
{
  return fifo_segment->h->fifos != 0;
}

static inline svm_fifo_t *
svm_fifo_segment_get_fifo_list (svm_fifo_segment_private_t * fifo_segment)
{
  return fifo_segment->h->fifos;
}

int svm_fifo_segment_init (svm_fifo_segment_private_t * s);
int svm_fifo_segment_create (svm_fifo_segment_create_args_t * a);
int svm_fifo_segment_create_process_private (svm_fifo_segment_create_args_t
					     * a);
void svm_fifo_segment_preallocate_fifo_pairs (svm_fifo_segment_private_t * s,
					      u32 rx_fifo_size,
					      u32 tx_fifo_size,
					      u32 * n_fifo_pairs);
int svm_fifo_segment_attach (svm_fifo_segment_create_args_t * a);
void svm_fifo_segment_delete (svm_fifo_segment_private_t * s);

svm_fifo_t *svm_fifo_segment_alloc_fifo (svm_fifo_segment_private_t * s,
					 u32 data_size_in_bytes,
					 svm_fifo_segment_freelist_t index);
void svm_fifo_segment_free_fifo (svm_fifo_segment_private_t * s,
				 svm_fifo_t * f,
				 svm_fifo_segment_freelist_t index);
void svm_fifo_segment_main_init (u64 baseva, u32 timeout_in_seconds);
u32 svm_fifo_segment_index (svm_fifo_segment_private_t * s);
u32 svm_fifo_segment_num_fifos (svm_fifo_segment_private_t * fifo_segment);
u32 svm_fifo_segment_num_free_fifos (svm_fifo_segment_private_t *
				     fifo_segment, u32 fifo_size_in_bytes);
void svm_fifo_segment_info (svm_fifo_segment_private_t * seg, uword * address,
			    u64 * size);

svm_fifo_segment_private_t *svm_fifo_segment_segments_pool (void);

format_function_t format_svm_fifo_segment;
format_function_t format_svm_fifo_segment_type;

#endif /* __included_ssvm_fifo_segment_h__ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
n">u8 *nl; if (!s) return indent; nl = vec_end (s) - 1; while (nl >= s) { if (*nl-- == '\n') break; indent++; } return indent; } #define _(f) u8 * f (u8 * s, va_list * va) /* Standard user-defined formats. */ _(format_vec32); _(format_vec_uword); _(format_ascii_bytes); _(format_hex_bytes); _(format_white_space); _(format_f64); _(format_time_interval); #ifdef CLIB_UNIX /* Unix specific formats. */ _(format_address_family); _(format_unix_arphrd); _(format_unix_interface_flags); _(format_network_address); _(format_network_protocol); _(format_network_port); _(format_sockaddr); _(format_ip4_tos_byte); _(format_ip4_packet); _(format_icmp4_type_and_code); _(format_ethernet_packet); _(format_hostname); _(format_timeval); _(format_time_float); _(format_signal); _(format_ucontext_pc); _(format_page_map); #endif #undef _ /* Unformat. */ typedef struct _unformat_input_t { /* Input buffer (vector). */ u8 *buffer; /* Current index in input buffer. */ uword index; /* Vector of buffer marks. Used to delineate pieces of the buffer for error reporting and for parse recovery. */ uword *buffer_marks; /* User's function to fill the buffer when its empty (and argument). */ uword (*fill_buffer) (struct _unformat_input_t * i); /* Return values for fill buffer function which indicate whether not input has been exhausted. */ #define UNFORMAT_END_OF_INPUT (~0) #define UNFORMAT_MORE_INPUT 0 /* User controlled argument to fill buffer function. */ void *fill_buffer_arg; } unformat_input_t; always_inline void unformat_init (unformat_input_t * i, uword (*fill_buffer) (unformat_input_t *), void *fill_buffer_arg) { clib_memset (i, 0, sizeof (i[0])); i->fill_buffer = fill_buffer; i->fill_buffer_arg = fill_buffer_arg; } always_inline void unformat_free (unformat_input_t * i) { vec_free (i->buffer); vec_free (i->buffer_marks); clib_memset (i, 0, sizeof (i[0])); } always_inline uword unformat_check_input (unformat_input_t * i) { /* Low level fill input function. */ extern uword _unformat_fill_input (unformat_input_t * i); if (i->index >= vec_len (i->buffer) && i->index != UNFORMAT_END_OF_INPUT) _unformat_fill_input (i); return i->index; } /* Return true if input is exhausted */ always_inline uword unformat_is_eof (unformat_input_t * input) { return unformat_check_input (input) == UNFORMAT_END_OF_INPUT; } /* Return next element in input vector, possibly calling fill input to get more. */ always_inline uword unformat_get_input (unformat_input_t * input) { uword i = unformat_check_input (input); if (i < vec_len (input->buffer)) { input->index = i + 1; i = input->buffer[i]; } return i; } /* Back up input pointer by one. */ always_inline void unformat_put_input (unformat_input_t * input) { input->index -= 1; } /* Peek current input character without advancing. */ always_inline uword unformat_peek_input (unformat_input_t * input) { uword c = unformat_get_input (input); if (c != UNFORMAT_END_OF_INPUT) unformat_put_input (input); return c; } /* Skip current input line. */ always_inline void unformat_skip_line (unformat_input_t * i) { uword c; while ((c = unformat_get_input (i)) != UNFORMAT_END_OF_INPUT && c != '\n') ; } uword unformat_skip_white_space (unformat_input_t * input); /* Unformat function. */ typedef uword (unformat_function_t) (unformat_input_t * input, va_list * args); /* External functions. */ /* General unformatting function with programmable input stream. */ uword unformat (unformat_input_t * i, const char *fmt, ...); /* Call user defined parse function. unformat_user (i, f, ...) is equivalent to unformat (i, "%U", f, ...) */ uword unformat_user (unformat_input_t * input, unformat_function_t * func, ...); /* Alternate version which allows for extensions. */ uword va_unformat (unformat_input_t * i, const char *fmt, va_list * args); /* Setup for unformat of Unix style command line. */ void unformat_init_command_line (unformat_input_t * input, char *argv[]); /* Setup for unformat of given string. */ void unformat_init_string (unformat_input_t * input, char *string, int string_len); always_inline void unformat_init_cstring (unformat_input_t * input, char *string) { unformat_init_string (input, string, strlen (string)); } /* Setup for unformat of given vector string; vector will be freed by unformat_string. */ void unformat_init_vector (unformat_input_t * input, u8 * vector_string); /* Format function for unformat input usable when an unformat error has occurred. */ u8 *format_unformat_error (u8 * s, va_list * va); #define unformat_parse_error(input) \ clib_error_return (0, "parse error `%U'", format_unformat_error, input) /* Print all input: not just error context. */ u8 *format_unformat_input (u8 * s, va_list * va); /* Unformat (parse) function which reads a %s string and converts it to and unformat_input_t. */ unformat_function_t unformat_input; /* Parse a line ending with \n and return it. */ unformat_function_t unformat_line; /* Parse a line ending with \n and return it as an unformat_input_t. */ unformat_function_t unformat_line_input; /* Parse a token containing given set of characters. */ unformat_function_t unformat_token; /* Parses a hexstring into a vector of bytes. */ unformat_function_t unformat_hex_string; /* Returns non-zero match if input is exhausted. Useful to ensure that the entire input matches with no trailing junk. */ unformat_function_t unformat_eof; /* Parse memory size e.g. 100, 100k, 100m, 100g. */ unformat_function_t unformat_memory_size; /* Unparse memory size e.g. 100, 100k, 100m, 100g. */ u8 *format_memory_size (u8 * s, va_list * va); /* Format c identifier: e.g. a_name -> "a name". */ u8 *format_c_identifier (u8 * s, va_list * va); /* Format hexdump with both hex and printable chars - compatible with text2pcap */ u8 *format_hexdump (u8 * s, va_list * va); /* Unix specific formats. */ #ifdef CLIB_UNIX /* Setup input from Unix file. */ void unformat_init_clib_file (unformat_input_t * input, int file_descriptor); /* Take input from Unix environment variable; returns 1 if variable exists zero otherwise. */ uword unformat_init_unix_env (unformat_input_t * input, char *var); /* Unformat unix group id (gid) specified as integer or string */ unformat_function_t unformat_unix_gid; #endif /* CLIB_UNIX */ /* Test code. */ int test_format_main (unformat_input_t * input); int test_unformat_main (unformat_input_t * input); /* This is not the right place for this, but putting it in vec.h created circular dependency problems. */ int test_vec_main (unformat_input_t * input); #endif /* included_format_h */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */