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>
46 #include <rte_memory.h>
47 #include <rte_malloc.h>
48 #include <rte_atomic.h>
51 #include "channel_monitor.h"
52 #include "channel_commands.h"
53 #include "channel_manager.h"
54 #include "power_manager.h"
56 #define RTE_LOGTYPE_CHANNEL_MONITOR RTE_LOGTYPE_USER1
58 #define MAX_EVENTS 256
61 static volatile unsigned run_loop
= 1;
62 static int global_event_fd
;
63 static struct epoll_event
*global_events_list
;
65 void channel_monitor_exit(void)
68 rte_free(global_events_list
);
72 process_request(struct channel_packet
*pkt
, struct channel_info
*chan_info
)
76 if (chan_info
== NULL
)
79 if (rte_atomic32_cmpset(&(chan_info
->status
), CHANNEL_MGR_CHANNEL_CONNECTED
,
80 CHANNEL_MGR_CHANNEL_PROCESSING
) == 0)
83 if (pkt
->command
== CPU_POWER
) {
84 core_mask
= get_pcpus_mask(chan_info
, pkt
->resource_id
);
86 RTE_LOG(ERR
, CHANNEL_MONITOR
, "Error get physical CPU mask for "
87 "channel '%s' using vCPU(%u)\n", chan_info
->channel_path
,
91 if (__builtin_popcountll(core_mask
) == 1) {
93 unsigned core_num
= __builtin_ffsll(core_mask
) - 1;
96 case(CPU_POWER_SCALE_MIN
):
97 power_manager_scale_core_min(core_num
);
99 case(CPU_POWER_SCALE_MAX
):
100 power_manager_scale_core_max(core_num
);
102 case(CPU_POWER_SCALE_DOWN
):
103 power_manager_scale_core_down(core_num
);
105 case(CPU_POWER_SCALE_UP
):
106 power_manager_scale_core_up(core_num
);
113 case(CPU_POWER_SCALE_MIN
):
114 power_manager_scale_mask_min(core_mask
);
116 case(CPU_POWER_SCALE_MAX
):
117 power_manager_scale_mask_max(core_mask
);
119 case(CPU_POWER_SCALE_DOWN
):
120 power_manager_scale_mask_down(core_mask
);
122 case(CPU_POWER_SCALE_UP
):
123 power_manager_scale_mask_up(core_mask
);
131 /* Return is not checked as channel status may have been set to DISABLED
132 * from management thread
134 rte_atomic32_cmpset(&(chan_info
->status
), CHANNEL_MGR_CHANNEL_PROCESSING
,
135 CHANNEL_MGR_CHANNEL_CONNECTED
);
141 add_channel_to_monitor(struct channel_info
**chan_info
)
143 struct channel_info
*info
= *chan_info
;
144 struct epoll_event event
;
146 event
.events
= EPOLLIN
;
147 event
.data
.ptr
= info
;
148 if (epoll_ctl(global_event_fd
, EPOLL_CTL_ADD
, info
->fd
, &event
) < 0) {
149 RTE_LOG(ERR
, CHANNEL_MONITOR
, "Unable to add channel '%s' "
150 "to epoll\n", info
->channel_path
);
157 remove_channel_from_monitor(struct channel_info
*chan_info
)
159 if (epoll_ctl(global_event_fd
, EPOLL_CTL_DEL
, chan_info
->fd
, NULL
) < 0) {
160 RTE_LOG(ERR
, CHANNEL_MONITOR
, "Unable to remove channel '%s' "
161 "from epoll\n", chan_info
->channel_path
);
168 channel_monitor_init(void)
170 global_event_fd
= epoll_create1(0);
171 if (global_event_fd
== 0) {
172 RTE_LOG(ERR
, CHANNEL_MONITOR
, "Error creating epoll context with "
173 "error %s\n", strerror(errno
));
176 global_events_list
= rte_malloc("epoll_events", sizeof(*global_events_list
)
177 * MAX_EVENTS
, RTE_CACHE_LINE_SIZE
);
178 if (global_events_list
== NULL
) {
179 RTE_LOG(ERR
, CHANNEL_MONITOR
, "Unable to rte_malloc for "
187 run_channel_monitor(void)
192 n_events
= epoll_wait(global_event_fd
, global_events_list
,
196 for (i
= 0; i
< n_events
; i
++) {
197 struct channel_info
*chan_info
= (struct channel_info
*)
198 global_events_list
[i
].data
.ptr
;
199 if ((global_events_list
[i
].events
& EPOLLERR
) ||
200 (global_events_list
[i
].events
& EPOLLHUP
)) {
201 RTE_LOG(DEBUG
, CHANNEL_MONITOR
, "Remote closed connection for "
202 "channel '%s'\n", chan_info
->channel_path
);
203 remove_channel(&chan_info
);
206 if (global_events_list
[i
].events
& EPOLLIN
) {
208 int n_bytes
, err
= 0;
209 struct channel_packet pkt
;
211 int buffer_len
= sizeof(pkt
);
213 while (buffer_len
> 0) {
214 n_bytes
= read(chan_info
->fd
, buffer
, buffer_len
);
215 if (n_bytes
== buffer_len
)
219 RTE_LOG(DEBUG
, CHANNEL_MONITOR
, "Received error on "
220 "channel '%s' read: %s\n",
221 chan_info
->channel_path
, strerror(err
));
222 remove_channel(&chan_info
);
225 buffer
= (char *)buffer
+ n_bytes
;
226 buffer_len
-= n_bytes
;
229 process_request(&pkt
, chan_info
);