vcl: support for eventfd mq signaling
[vpp.git] / src / vcl / vcl_private.c
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vcl/vcl_private.h>
17
18 vcl_cut_through_registration_t *
19 vcl_ct_registration_lock_and_alloc (void)
20 {
21   vcl_cut_through_registration_t *cr;
22   pool_get (vcm->cut_through_registrations, cr);
23   clib_spinlock_lock (&vcm->ct_registration_lock);
24   memset (cr, 0, sizeof (*cr));
25   cr->epoll_evt_conn_index = -1;
26   return cr;
27 }
28
29 u32
30 vcl_ct_registration_index (vcl_cut_through_registration_t * ctr)
31 {
32   return (ctr - vcm->cut_through_registrations);
33 }
34
35 void
36 vcl_ct_registration_unlock (void)
37 {
38   clib_spinlock_unlock (&vcm->ct_registration_lock);
39 }
40
41 vcl_cut_through_registration_t *
42 vcl_ct_registration_get (u32 ctr_index)
43 {
44   if (pool_is_free_index (vcm->cut_through_registrations, ctr_index))
45     return 0;
46   return pool_elt_at_index (vcm->cut_through_registrations, ctr_index);
47 }
48
49 vcl_cut_through_registration_t *
50 vcl_ct_registration_lock_and_lookup (uword mq_addr)
51 {
52   uword *p;
53   clib_spinlock_lock (&vcm->ct_registration_lock);
54   p = hash_get (vcm->ct_registration_by_mq, mq_addr);
55   if (!p)
56     return 0;
57   return vcl_ct_registration_get (p[0]);
58 }
59
60 void
61 vcl_ct_registration_lookup_add (uword mq_addr, u32 ctr_index)
62 {
63   hash_set (vcm->ct_registration_by_mq, mq_addr, ctr_index);
64 }
65
66 void
67 vcl_ct_registration_lookup_del (uword mq_addr)
68 {
69   hash_unset (vcm->ct_registration_by_mq, mq_addr);
70 }
71
72 void
73 vcl_ct_registration_del (vcl_cut_through_registration_t * ctr)
74 {
75   pool_put (vcm->cut_through_registrations, ctr);
76 }
77
78 vcl_mq_evt_conn_t *
79 vcl_mq_evt_conn_alloc (void)
80 {
81   vcl_mq_evt_conn_t *mqc;
82   pool_get (vcm->mq_evt_conns, mqc);
83   memset (mqc, 0, sizeof (*mqc));
84   return mqc;
85 }
86
87 u32
88 vcl_mq_evt_conn_index (vcl_mq_evt_conn_t * mqc)
89 {
90   return (mqc - vcm->mq_evt_conns);
91 }
92
93 vcl_mq_evt_conn_t *
94 vcl_mq_evt_conn_get (u32 mq_conn_idx)
95 {
96   return pool_elt_at_index (vcm->mq_evt_conns, mq_conn_idx);
97 }
98
99 int
100 vcl_mq_epoll_add_evfd (svm_msg_q_t * mq)
101 {
102   struct epoll_event e = { 0 };
103   vcl_mq_evt_conn_t *mqc;
104   u32 mqc_index;
105   int mq_fd;
106
107   mq_fd = svm_msg_q_get_consumer_eventfd (mq);
108
109   if (vcm->mqs_epfd < 0 || mq_fd == -1)
110     return -1;
111
112   mqc = vcl_mq_evt_conn_alloc ();
113   mqc_index = vcl_mq_evt_conn_index (mqc);
114   mqc->mq_fd = mq_fd;
115   mqc->mq = mq;
116
117   e.events = EPOLLIN;
118   e.data.u32 = mqc_index;
119   if (epoll_ctl (vcm->mqs_epfd, EPOLL_CTL_ADD, mq_fd, &e) < 0)
120     {
121       clib_warning ("failed to add mq eventfd to mq epoll fd");
122       return -1;
123     }
124
125   return mqc_index;
126 }
127
128 int
129 vcl_mq_epoll_del_evfd (u32 mqc_index)
130 {
131   vcl_mq_evt_conn_t *mqc;
132
133   if (vcm->mqs_epfd || mqc_index == ~0)
134     return -1;
135
136   mqc = vcl_mq_evt_conn_get (mqc_index);
137   if (epoll_ctl (vcm->mqs_epfd, EPOLL_CTL_DEL, mqc->mq_fd, 0) < 0)
138     {
139       clib_warning ("failed to del mq eventfd to mq epoll fd");
140       return -1;
141     }
142   return 0;
143 }
144
145 /*
146  * fd.io coding-style-patch-verification: ON
147  *
148  * Local Variables:
149  * eval: (c-set-style "gnu")
150  * End:
151  */