4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include <sys/types.h>
42 #include <sys/epoll.h>
43 #include <sys/queue.h>
45 #include <rte_config.h>
47 #include <rte_memory.h>
48 #include <rte_malloc.h>
49 #include <rte_atomic.h>
52 #include "channel_monitor.h"
53 #include "channel_commands.h"
54 #include "channel_manager.h"
55 #include "power_manager.h"
57 #define RTE_LOGTYPE_CHANNEL_MONITOR RTE_LOGTYPE_USER1
59 #define MAX_EVENTS 256
62 static volatile unsigned run_loop = 1;
63 static int global_event_fd;
64 static struct epoll_event *global_events_list;
66 void channel_monitor_exit(void)
69 rte_free(global_events_list);
73 process_request(struct channel_packet *pkt, struct channel_info *chan_info)
77 if (chan_info == NULL)
80 if (rte_atomic32_cmpset(&(chan_info->status), CHANNEL_MGR_CHANNEL_CONNECTED,
81 CHANNEL_MGR_CHANNEL_PROCESSING) == 0)
84 if (pkt->command == CPU_POWER) {
85 core_mask = get_pcpus_mask(chan_info, pkt->resource_id);
87 RTE_LOG(ERR, CHANNEL_MONITOR, "Error get physical CPU mask for "
88 "channel '%s' using vCPU(%u)\n", chan_info->channel_path,
92 if (__builtin_popcountll(core_mask) == 1) {
94 unsigned core_num = __builtin_ffsll(core_mask) - 1;
97 case(CPU_POWER_SCALE_MIN):
98 power_manager_scale_core_min(core_num);
100 case(CPU_POWER_SCALE_MAX):
101 power_manager_scale_core_max(core_num);
103 case(CPU_POWER_SCALE_DOWN):
104 power_manager_scale_core_down(core_num);
106 case(CPU_POWER_SCALE_UP):
107 power_manager_scale_core_up(core_num);
114 case(CPU_POWER_SCALE_MIN):
115 power_manager_scale_mask_min(core_mask);
117 case(CPU_POWER_SCALE_MAX):
118 power_manager_scale_mask_max(core_mask);
120 case(CPU_POWER_SCALE_DOWN):
121 power_manager_scale_mask_down(core_mask);
123 case(CPU_POWER_SCALE_UP):
124 power_manager_scale_mask_up(core_mask);
132 /* Return is not checked as channel status may have been set to DISABLED
133 * from management thread
135 rte_atomic32_cmpset(&(chan_info->status), CHANNEL_MGR_CHANNEL_PROCESSING,
136 CHANNEL_MGR_CHANNEL_CONNECTED);
142 add_channel_to_monitor(struct channel_info **chan_info)
144 struct channel_info *info = *chan_info;
145 struct epoll_event event;
147 event.events = EPOLLIN;
148 event.data.ptr = info;
149 if (epoll_ctl(global_event_fd, EPOLL_CTL_ADD, info->fd, &event) < 0) {
150 RTE_LOG(ERR, CHANNEL_MONITOR, "Unable to add channel '%s' "
151 "to epoll\n", info->channel_path);
158 remove_channel_from_monitor(struct channel_info *chan_info)
160 if (epoll_ctl(global_event_fd, EPOLL_CTL_DEL, chan_info->fd, NULL) < 0) {
161 RTE_LOG(ERR, CHANNEL_MONITOR, "Unable to remove channel '%s' "
162 "from epoll\n", chan_info->channel_path);
169 channel_monitor_init(void)
171 global_event_fd = epoll_create1(0);
172 if (global_event_fd == 0) {
173 RTE_LOG(ERR, CHANNEL_MONITOR, "Error creating epoll context with "
174 "error %s\n", strerror(errno));
177 global_events_list = rte_malloc("epoll_events", sizeof(*global_events_list)
178 * MAX_EVENTS, RTE_CACHE_LINE_SIZE);
179 if (global_events_list == NULL) {
180 RTE_LOG(ERR, CHANNEL_MONITOR, "Unable to rte_malloc for "
188 run_channel_monitor(void)
193 n_events = epoll_wait(global_event_fd, global_events_list,
197 for (i = 0; i < n_events; i++) {
198 struct channel_info *chan_info = (struct channel_info *)
199 global_events_list[i].data.ptr;
200 if ((global_events_list[i].events & EPOLLERR) ||
201 (global_events_list[i].events & EPOLLHUP)) {
202 RTE_LOG(DEBUG, CHANNEL_MONITOR, "Remote closed connection for "
203 "channel '%s'\n", chan_info->channel_path);
204 remove_channel(&chan_info);
207 if (global_events_list[i].events & EPOLLIN) {
209 int n_bytes, err = 0;
210 struct channel_packet pkt;
212 int buffer_len = sizeof(pkt);
214 while (buffer_len > 0) {
215 n_bytes = read(chan_info->fd, buffer, buffer_len);
216 if (n_bytes == buffer_len)
220 RTE_LOG(DEBUG, CHANNEL_MONITOR, "Received error on "
221 "channel '%s' read: %s\n",
222 chan_info->channel_path, strerror(err));
223 remove_channel(&chan_info);
226 buffer = (char *)buffer + n_bytes;
227 buffer_len -= n_bytes;
230 process_request(&pkt, chan_info);