1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 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 16 * distribution. 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. 20 * 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. 32 */ 33 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <stdint.h> 37 #include <unistd.h> 38 #include <pthread.h> 39 #include <sched.h> 40 #include <assert.h> 41 #include <string.h> 42 43 #include <rte_lcore.h> 44 #include <rte_memory.h> 45 #include <rte_log.h> 46 47 #include "eal_thread.h" 48 49 RTE_DECLARE_PER_LCORE(unsigned , _socket_id); 50 51 unsigned rte_socket_id(void) 52 { 53 return RTE_PER_LCORE(_socket_id); 54 } 55 56 int 57 rte_lcore_has_role(unsigned int lcore_id, enum rte_lcore_role_t role) 58 { 59 struct rte_config *cfg = rte_eal_get_configuration(); 60 61 if (lcore_id >= RTE_MAX_LCORE) 62 return -EINVAL; 63 64 if (cfg->lcore_role[lcore_id] == role) 65 return 0; 66 67 return -EINVAL; 68 } 69 70 int eal_cpuset_socket_id(rte_cpuset_t *cpusetp) 71 { 72 unsigned cpu = 0; 73 int socket_id = SOCKET_ID_ANY; 74 int sid; 75 76 if (cpusetp == NULL) 77 return SOCKET_ID_ANY; 78 79 do { 80 if (!CPU_ISSET(cpu, cpusetp)) 81 continue; 82 83 if (socket_id == SOCKET_ID_ANY) 84 socket_id = eal_cpu_socket_id(cpu); 85 86 sid = eal_cpu_socket_id(cpu); 87 if (socket_id != sid) { 88 socket_id = SOCKET_ID_ANY; 89 break; 90 } 91 92 } while (++cpu < RTE_MAX_LCORE); 93 94 return socket_id; 95 } 96 97 int 98 rte_thread_set_affinity(rte_cpuset_t *cpusetp) 99 { 100 int s; 101 unsigned lcore_id; 102 pthread_t tid; 103 104 tid = pthread_self(); 105 106 s = pthread_setaffinity_np(tid, sizeof(rte_cpuset_t), cpusetp); 107 if (s != 0) { 108 RTE_LOG(ERR, EAL, "pthread_setaffinity_np failed\n"); 109 return -1; 110 } 111 112 /* store socket_id in TLS for quick access */ 113 RTE_PER_LCORE(_socket_id) = 114 eal_cpuset_socket_id(cpusetp); 115 116 /* store cpuset in TLS for quick access */ 117 memmove(&RTE_PER_LCORE(_cpuset), cpusetp, 118 sizeof(rte_cpuset_t)); 119 120 lcore_id = rte_lcore_id(); 121 if (lcore_id != (unsigned)LCORE_ID_ANY) { 122 /* EAL thread will update lcore_config */ 123 lcore_config[lcore_id].socket_id = RTE_PER_LCORE(_socket_id); 124 memmove(&lcore_config[lcore_id].cpuset, cpusetp, 125 sizeof(rte_cpuset_t)); 126 } 127 128 return 0; 129 } 130 131 void 132 rte_thread_get_affinity(rte_cpuset_t *cpusetp) 133 { 134 assert(cpusetp); 135 memmove(cpusetp, &RTE_PER_LCORE(_cpuset), 136 sizeof(rte_cpuset_t)); 137 } 138 139 int 140 eal_thread_dump_affinity(char *str, unsigned size) 141 { 142 rte_cpuset_t cpuset; 143 unsigned cpu; 144 int ret; 145 unsigned int out = 0; 146 147 rte_thread_get_affinity(&cpuset); 148 149 for (cpu = 0; cpu < RTE_MAX_LCORE; cpu++) { 150 if (!CPU_ISSET(cpu, &cpuset)) 151 continue; 152 153 ret = snprintf(str + out, 154 size - out, "%u,", cpu); 155 if (ret < 0 || (unsigned)ret >= size - out) { 156 /* string will be truncated */ 157 ret = -1; 158 goto exit; 159 } 160 161 out += ret; 162 } 163 164 ret = 0; 165 exit: 166 /* remove the last separator */ 167 if (out > 0) 168 str[out - 1] = '\0'; 169 170 return ret; 171 } 172