aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/session/segment_manager.h
blob: 2b6f43feba705a070c719e295c98db5cf9652f26 (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
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * Copyright (c) 2017-2019 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 SRC_VNET_SESSION_SEGMENT_MANAGER_H_
#define SRC_VNET_SESSION_SEGMENT_MANAGER_H_

#include <vnet/vnet.h>
#include <svm/svm_fifo_segment.h>
#include <svm/message_queue.h>
#include <vlibmemory/api.h>
#include <vppinfra/lock.h>
#include <vppinfra/valloc.h>

typedef struct _segment_manager_properties
{
  u32 rx_fifo_size;			/**< receive fifo size */
  u32 tx_fifo_size;			/**< transmit fifo size */
  u32 evt_q_size;			/**< event queue length */
  u32 segment_size;			/**< first segment size */
  u32 prealloc_fifos;			/**< preallocated fifo pairs */
  u32 add_segment_size;			/**< additional segment size */
  u8 add_segment:1;			/**< can add new segments flag */
  u8 use_mq_eventfd:1;			/**< use eventfds for mqs flag */
  u8 reserved:6;			/**< reserved flags */
  ssvm_segment_type_t segment_type;	/**< seg type: if set to SSVM_N_TYPES,
					     private segments are used */
} segment_manager_properties_t;

typedef struct _segment_manager
{
  /** Pool of segments allocated by this manager */
  svm_fifo_segment_private_t *segments;

  /** rwlock that protects the segments pool */
  clib_rwlock_t segments_rwlock;

  /** Owner app worker index */
  u32 app_wrk_index;

  /**
   * First segment should not be deleted unless segment manger is deleted.
   * This also indicates that the segment manager is the first to have been
   * allocated for the app.
   */
  u8 first_is_protected;

  /**
   * App event queue allocated in first segment
   */
  svm_msg_q_t *event_queue;
} segment_manager_t;

#define segment_manager_foreach_segment_w_lock(VAR, SM, BODY)		\
do {									\
    clib_rwlock_reader_lock (&(SM)->segments_rwlock);			\
    pool_foreach((VAR), ((SM)->segments), (BODY));			\
    clib_rwlock_reader_unlock (&(SM)->segments_rwlock);			\
} while (0)

typedef struct segment_manager_main_
{
  /** Pool of segment managers */
  segment_manager_t *segment_managers;

  /** Virtual address allocator */
  clib_valloc_main_t va_allocator;

} segment_manager_main_t;

extern segment_manager_main_t segment_manager_main;

typedef struct segment_manager_main_init_args_
{
  u64 baseva;
  u64 size;
} segment_manager_main_init_args_t;

#define SEGMENT_MANAGER_INVALID_APP_INDEX ((u32) ~0)

/** Pool of segment managers */
extern segment_manager_t *segment_managers;

always_inline segment_manager_t *
segment_manager_get (u32 index)
{
  return pool_elt_at_index (segment_manager_main.segment_managers, index);
}

always_inline segment_manager_t *
segment_manager_get_if_valid (u32 index)
{
  if (pool_is_free_index (segment_manager_main.segment_managers, index))
    return 0;
  return pool_elt_at_index (segment_manager_main.segment_managers, index);
}

always_inline u32
segment_manager_index (segment_manager_t * sm)
{
  return sm - segment_manager_main.segment_managers;
}

always_inline svm_msg_q_t *
segment_manager_event_queue (segment_manager_t * sm)
{
  return sm->event_queue;
}

always_inline u64
segment_manager_make_segment_handle (u32 segment_manager_index,
				     u32 segment_index)
{
  return (((u64) segment_manager_index << 32) | segment_index);
}

u64 segment_manager_segment_handle (segment_manager_t * sm,
				    svm_fifo_segment_private_t * segment);

segment_manager_t *segment_manager_new ();
int segment_manager_init (segment_manager_t * sm, u32 first_seg_size,
			  u32 prealloc_fifo_pairs);

svm_fifo_segment_private_t *segment_manager_get_segment (segment_manager_t *,
							 u32 segment_index);
svm_fifo_segment_private_t *segment_manager_get_segment_w_handle (u64);
svm_fifo_segment_private_t
  * segment_manager_get_segment_w_lock (segment_manager_t * sm,
					u32 segment_index);
int segment_manager_add_segment (segment_manager_t * sm, u32 segment_size);
void segment_manager_del_segment (segment_manager_t * sm,
				  svm_fifo_segment_private_t * fs);
void segment_manager_segment_reader_unlock (segment_manager_t * sm);
void segment_manager_segment_writer_unlock (segment_manager_t * sm);

int segment_manager_add_first_segment (segment_manager_t * sm,
				       u32 segment_size);
void segment_manager_del_sessions (segment_manager_t * sm);
void segment_manager_del (segment_manager_t * sm);
void segment_manager_init_del (segment_manager_t * sm);
u8 segment_manager_has_fifos (segment_manager_t * sm);
int segment_manager_alloc_session_fifos (segment_manager_t * sm,
					 svm_fifo_t ** server_rx_fifo,
					 svm_fifo_t ** server_tx_fifo);
int segment_manager_try_alloc_fifos (svm_fifo_segment_private_t * fs,
				     u32 rx_fifo_size, u32 tx_fifo_size,
				     svm_fifo_t ** rx_fifo,
				     svm_fifo_t ** tx_fifo);
void segment_manager_dealloc_fifos (svm_fifo_t * rx_fifo,
				    svm_fifo_t * tx_fifo);
u32 segment_manager_evt_q_expected_size (u32 q_size);
svm_msg_q_t *segment_manager_alloc_queue (svm_fifo_segment_private_t * fs,
					  segment_manager_properties_t *
					  props);
void segment_manager_dealloc_queue (segment_manager_t * sm, svm_queue_t * q);
void segment_manager_app_detach (segment_manager_t * sm);

void segment_manager_main_init (segment_manager_main_init_args_t * a);
segment_manager_properties_t
  * segment_manager_properties_init (segment_manager_properties_t * sm);

#endif /* SRC_VNET_SESSION_SEGMENT_MANAGER_H_ */
/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */