/src/openvswitch/lib/poll-loop.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at: |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include <config.h> |
18 | | #include "openvswitch/poll-loop.h" |
19 | | #include <errno.h> |
20 | | #include <inttypes.h> |
21 | | #include <poll.h> |
22 | | #include <stdlib.h> |
23 | | #include <string.h> |
24 | | #include "coverage.h" |
25 | | #include "openvswitch/dynamic-string.h" |
26 | | #include "fatal-signal.h" |
27 | | #include "openvswitch/list.h" |
28 | | #include "ovs-thread.h" |
29 | | #include "seq.h" |
30 | | #include "socket-util.h" |
31 | | #include "timeval.h" |
32 | | #include "openvswitch/vlog.h" |
33 | | #include "openvswitch/hmap.h" |
34 | | #include "hash.h" |
35 | | |
36 | | VLOG_DEFINE_THIS_MODULE(poll_loop); |
37 | | |
38 | | COVERAGE_DEFINE(poll_create_node); |
39 | | COVERAGE_DEFINE(poll_zero_timeout); |
40 | | |
41 | | struct poll_node { |
42 | | struct hmap_node hmap_node; |
43 | | struct pollfd pollfd; /* Events to pass to time_poll(). */ |
44 | | const char *where; /* Where poll_node was created. */ |
45 | | }; |
46 | | |
47 | | struct poll_loop { |
48 | | /* All active poll waiters. */ |
49 | | struct hmap poll_nodes; |
50 | | |
51 | | /* Time at which to wake up the next call to poll_block(), LLONG_MIN to |
52 | | * wake up immediately, or LLONG_MAX to wait forever. */ |
53 | | long long int timeout_when; /* In msecs as returned by time_msec(). */ |
54 | | const char *timeout_where; /* Where 'timeout_when' was set. */ |
55 | | }; |
56 | | |
57 | | static struct poll_loop *poll_loop(void); |
58 | | |
59 | | /* Look up the node with same fd. */ |
60 | | static struct poll_node * |
61 | | find_poll_node(struct poll_loop *loop, int fd) |
62 | 0 | { |
63 | 0 | struct poll_node *node; |
64 | |
|
65 | 0 | HMAP_FOR_EACH_WITH_HASH (node, hmap_node, hash_int(fd, 0), |
66 | 0 | &loop->poll_nodes) { |
67 | 0 | if (node->pollfd.fd == fd) { |
68 | 0 | return node; |
69 | 0 | } |
70 | 0 | } |
71 | 0 | return NULL; |
72 | 0 | } |
73 | | |
74 | | /* Registers 'fd' as waiting for the specified 'events' (which should be |
75 | | * POLLIN or POLLOUT or POLLIN | POLLOUT). The following call to |
76 | | * poll_block() will wake up when 'fd' becomes ready for one or more of the |
77 | | * requested events. The 'fd's are given to poll() function later. |
78 | | * |
79 | | * The event registration is one-shot: only the following call to |
80 | | * poll_block() is affected. The event will need to be re-registered after |
81 | | * poll_block() is called if it is to persist. |
82 | | * |
83 | | * ('where' is used in debug logging. Commonly one would use poll_fd_wait() to |
84 | | * automatically provide the caller's source file and line number for |
85 | | * 'where'.) */ |
86 | | static void |
87 | | poll_create_node(int fd, short int events, const char *where) |
88 | 0 | { |
89 | 0 | struct poll_loop *loop = poll_loop(); |
90 | 0 | struct poll_node *node; |
91 | |
|
92 | 0 | COVERAGE_INC(poll_create_node); |
93 | | |
94 | | /* Check for duplicate. If found, "or" the events. */ |
95 | 0 | node = find_poll_node(loop, fd); |
96 | 0 | if (node) { |
97 | 0 | node->pollfd.events |= events; |
98 | 0 | } else { |
99 | 0 | node = xzalloc(sizeof *node); |
100 | 0 | hmap_insert(&loop->poll_nodes, &node->hmap_node, hash_int(fd, 0)); |
101 | 0 | node->pollfd.fd = fd; |
102 | 0 | node->pollfd.events = events; |
103 | 0 | node->where = where; |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | | /* Registers 'fd' as waiting for the specified 'events' (which should be POLLIN |
108 | | * or POLLOUT or POLLIN | POLLOUT). The following call to poll_block() will |
109 | | * wake up when 'fd' becomes ready for one or more of the requested events. |
110 | | * |
111 | | * The event registration is one-shot: only the following call to poll_block() |
112 | | * is affected. The event will need to be re-registered after poll_block() is |
113 | | * called if it is to persist. |
114 | | * |
115 | | * ('where' is used in debug logging. Commonly one would use poll_fd_wait() to |
116 | | * automatically provide the caller's source file and line number for |
117 | | * 'where'.) */ |
118 | | void |
119 | | poll_fd_wait_at(int fd, short int events, const char *where) |
120 | 0 | { |
121 | 0 | poll_create_node(fd, events, where); |
122 | 0 | } |
123 | | |
124 | | /* Causes the following call to poll_block() to block for no more than 'msec' |
125 | | * milliseconds. If 'msec' is nonpositive, the following call to poll_block() |
126 | | * will not block at all. |
127 | | * |
128 | | * The timer registration is one-shot: only the following call to poll_block() |
129 | | * is affected. The timer will need to be re-registered after poll_block() is |
130 | | * called if it is to persist. |
131 | | * |
132 | | * ('where' is used in debug logging. Commonly one would use poll_timer_wait() |
133 | | * to automatically provide the caller's source file and line number for |
134 | | * 'where'.) */ |
135 | | void |
136 | | poll_timer_wait_at(long long int msec, const char *where) |
137 | 0 | { |
138 | 0 | long long int now = time_msec(); |
139 | 0 | long long int when; |
140 | |
|
141 | 0 | if (msec <= 0) { |
142 | | /* Wake up immediately. */ |
143 | 0 | when = LLONG_MIN; |
144 | 0 | } else if ((unsigned long long int) now + msec <= LLONG_MAX) { |
145 | | /* Normal case. */ |
146 | 0 | when = now + msec; |
147 | 0 | } else { |
148 | | /* now + msec would overflow. */ |
149 | 0 | when = LLONG_MAX; |
150 | 0 | } |
151 | |
|
152 | 0 | poll_timer_wait_until_at(when, where); |
153 | 0 | } |
154 | | |
155 | | /* Causes the following call to poll_block() to wake up when the current time, |
156 | | * as returned by time_msec(), reaches 'when' or later. If 'when' is earlier |
157 | | * than the current time, the following call to poll_block() will not block at |
158 | | * all. |
159 | | * |
160 | | * The timer registration is one-shot: only the following call to poll_block() |
161 | | * is affected. The timer will need to be re-registered after poll_block() is |
162 | | * called if it is to persist. |
163 | | * |
164 | | * ('where' is used in debug logging. Commonly one would use |
165 | | * poll_timer_wait_until() to automatically provide the caller's source file |
166 | | * and line number for 'where'.) */ |
167 | | void |
168 | | poll_timer_wait_until_at(long long int when, const char *where) |
169 | 0 | { |
170 | 0 | struct poll_loop *loop = poll_loop(); |
171 | 0 | if (when < loop->timeout_when) { |
172 | 0 | loop->timeout_when = when; |
173 | 0 | loop->timeout_where = where; |
174 | 0 | } |
175 | 0 | } |
176 | | |
177 | | /* Causes the following call to poll_block() to wake up immediately, without |
178 | | * blocking. |
179 | | * |
180 | | * ('where' is used in debug logging. Commonly one would use |
181 | | * poll_immediate_wake() to automatically provide the caller's source file and |
182 | | * line number for 'where'.) */ |
183 | | void |
184 | | poll_immediate_wake_at(const char *where) |
185 | 0 | { |
186 | 0 | poll_timer_wait_at(0, where); |
187 | 0 | } |
188 | | |
189 | | /* Logs, if appropriate, that the poll loop was awakened by an event |
190 | | * registered at 'where' (typically a source file and line number). The other |
191 | | * arguments have two possible interpretations: |
192 | | * |
193 | | * - If 'pollfd' is nonnull then it should be the "struct pollfd" that caused |
194 | | * the wakeup. 'timeout' is ignored. |
195 | | * |
196 | | * - If 'pollfd' is NULL then 'timeout' is the number of milliseconds after |
197 | | * which the poll loop woke up. |
198 | | */ |
199 | | static void |
200 | | log_wakeup(const char *where, const struct pollfd *pollfd, int timeout) |
201 | 0 | { |
202 | 0 | static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 10); |
203 | 0 | enum vlog_level level; |
204 | 0 | int cpu_usage; |
205 | 0 | struct ds s; |
206 | |
|
207 | 0 | cpu_usage = get_cpu_usage(); |
208 | 0 | if (VLOG_IS_DBG_ENABLED()) { |
209 | 0 | level = VLL_DBG; |
210 | 0 | } else if (cpu_usage > 50 |
211 | 0 | && !thread_is_pmd() |
212 | 0 | && !VLOG_DROP_INFO(&rl)) { |
213 | 0 | level = VLL_INFO; |
214 | 0 | } else { |
215 | 0 | return; |
216 | 0 | } |
217 | | |
218 | 0 | ds_init(&s); |
219 | 0 | ds_put_cstr(&s, "wakeup due to "); |
220 | 0 | if (pollfd) { |
221 | 0 | char *description = describe_fd(pollfd->fd); |
222 | 0 | if (pollfd->revents & POLLIN) { |
223 | 0 | ds_put_cstr(&s, "[POLLIN]"); |
224 | 0 | } |
225 | 0 | if (pollfd->revents & POLLOUT) { |
226 | 0 | ds_put_cstr(&s, "[POLLOUT]"); |
227 | 0 | } |
228 | 0 | if (pollfd->revents & POLLERR) { |
229 | 0 | ds_put_cstr(&s, "[POLLERR]"); |
230 | 0 | } |
231 | 0 | if (pollfd->revents & POLLHUP) { |
232 | 0 | ds_put_cstr(&s, "[POLLHUP]"); |
233 | 0 | } |
234 | 0 | if (pollfd->revents & POLLNVAL) { |
235 | 0 | ds_put_cstr(&s, "[POLLNVAL]"); |
236 | 0 | } |
237 | 0 | ds_put_format(&s, " on fd %d (%s)", pollfd->fd, description); |
238 | 0 | free(description); |
239 | 0 | } else { |
240 | 0 | ds_put_format(&s, "%d-ms timeout", timeout); |
241 | 0 | } |
242 | 0 | if (where) { |
243 | 0 | ds_put_format(&s, " at %s", where); |
244 | 0 | } |
245 | 0 | if (cpu_usage >= 0) { |
246 | 0 | ds_put_format(&s, " (%d%% CPU usage)", cpu_usage); |
247 | 0 | } |
248 | 0 | VLOG(level, "%s", ds_cstr(&s)); |
249 | 0 | ds_destroy(&s); |
250 | 0 | } |
251 | | |
252 | | static void |
253 | | free_poll_nodes(struct poll_loop *loop) |
254 | 0 | { |
255 | 0 | struct poll_node *node; |
256 | |
|
257 | 0 | HMAP_FOR_EACH_SAFE (node, hmap_node, &loop->poll_nodes) { |
258 | 0 | hmap_remove(&loop->poll_nodes, &node->hmap_node); |
259 | 0 | free(node); |
260 | 0 | } |
261 | 0 | } |
262 | | |
263 | | /* Blocks until one or more of the events registered with poll_fd_wait() |
264 | | * occurs, or until the minimum duration registered with poll_timer_wait() |
265 | | * elapses, or not at all if poll_immediate_wake() has been called. */ |
266 | | void |
267 | | poll_block(void) |
268 | 0 | { |
269 | 0 | struct poll_loop *loop = poll_loop(); |
270 | 0 | struct poll_node *node; |
271 | 0 | struct pollfd *pollfds; |
272 | 0 | int elapsed; |
273 | 0 | int retval; |
274 | 0 | int i; |
275 | | |
276 | | /* Register fatal signal events before actually doing any real work for |
277 | | * poll_block. */ |
278 | 0 | fatal_signal_wait(); |
279 | |
|
280 | 0 | if (loop->timeout_when == LLONG_MIN) { |
281 | 0 | COVERAGE_INC(poll_zero_timeout); |
282 | 0 | } |
283 | |
|
284 | 0 | timewarp_run(); |
285 | 0 | pollfds = xmalloc(hmap_count(&loop->poll_nodes) * sizeof *pollfds); |
286 | | |
287 | | /* Populate with all the fds and events. */ |
288 | 0 | i = 0; |
289 | 0 | HMAP_FOR_EACH (node, hmap_node, &loop->poll_nodes) { |
290 | 0 | pollfds[i++] = node->pollfd; |
291 | 0 | } |
292 | |
|
293 | 0 | retval = time_poll(pollfds, hmap_count(&loop->poll_nodes), |
294 | 0 | loop->timeout_when, &elapsed); |
295 | 0 | if (retval < 0) { |
296 | 0 | static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); |
297 | 0 | VLOG_ERR_RL(&rl, "poll: %s", ovs_strerror(-retval)); |
298 | 0 | } else if (!retval) { |
299 | 0 | log_wakeup(loop->timeout_where, NULL, elapsed); |
300 | 0 | } else if (get_cpu_usage() > 50 || VLOG_IS_DBG_ENABLED()) { |
301 | 0 | i = 0; |
302 | 0 | HMAP_FOR_EACH (node, hmap_node, &loop->poll_nodes) { |
303 | 0 | if (pollfds[i].revents) { |
304 | 0 | log_wakeup(node->where, &pollfds[i], 0); |
305 | 0 | } |
306 | 0 | i++; |
307 | 0 | } |
308 | 0 | } |
309 | |
|
310 | 0 | free_poll_nodes(loop); |
311 | 0 | loop->timeout_when = LLONG_MAX; |
312 | 0 | loop->timeout_where = NULL; |
313 | 0 | free(pollfds); |
314 | | |
315 | | /* Handle any pending signals before doing anything else. */ |
316 | 0 | fatal_signal_run(); |
317 | |
|
318 | 0 | seq_woke(); |
319 | 0 | } |
320 | | |
321 | | static void |
322 | | free_poll_loop(void *loop_) |
323 | 0 | { |
324 | 0 | struct poll_loop *loop = loop_; |
325 | |
|
326 | 0 | free_poll_nodes(loop); |
327 | 0 | hmap_destroy(&loop->poll_nodes); |
328 | 0 | free(loop); |
329 | 0 | } |
330 | | |
331 | | static struct poll_loop * |
332 | | poll_loop(void) |
333 | 0 | { |
334 | 0 | static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; |
335 | 0 | static pthread_key_t key; |
336 | 0 | struct poll_loop *loop; |
337 | |
|
338 | 0 | if (ovsthread_once_start(&once)) { |
339 | 0 | xpthread_key_create(&key, free_poll_loop); |
340 | 0 | ovsthread_once_done(&once); |
341 | 0 | } |
342 | |
|
343 | 0 | loop = pthread_getspecific(key); |
344 | 0 | if (!loop) { |
345 | 0 | loop = xzalloc(sizeof *loop); |
346 | | loop->timeout_when = LLONG_MAX; |
347 | 0 | hmap_init(&loop->poll_nodes); |
348 | 0 | xpthread_setspecific(key, loop); |
349 | 0 | } |
350 | 0 | return loop; |
351 | 0 | } |
352 | | |