diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 23e46bd208d3291438b79dc687ea35b707274ec8..b50c017a92d873061302d9e18ff94af11da19d6b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -261,6 +261,7 @@ endif (${ENABLE_ITTI}) add_boolean_option(RTAI False "Use RTAI") if (${RTAI}) set(LOWLATENCY False) + set(CPU_AFFINITY False) add_definitions("-DENABLE_RTAI_CLOCK") add_definitions("-DCONFIG_RTAI_LXRT_INLINE") include_directories ("/usr/realtime/include") @@ -576,7 +577,6 @@ elseif (${RF_BOARD} STREQUAL "OAI_LMSSDR") LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/lms7002m") LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/Si5351C") set(HW_SOURCE ${HW_SOURCE} ${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp) - set(LOWLATENCY False) set(option_HW_lib "-lLMS_SDR -lLMS7002M -lSi5351C -rdynamic -ldl") elseif (${RF_BOARD} STREQUAL "CPRIGW") @@ -606,6 +606,7 @@ endif (${TRANSP_PRO} STREQUAL "ETHERNET") include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON") Message("LOWLATENCY flag is ${LOWLATENCY}") +Message("CPU_Affinity flag is ${CPU_AFFINITY}") ############################################################## # ???!!! TO BE DOCUMENTED OPTIONS !!!??? @@ -619,6 +620,7 @@ add_boolean_option(RRC_DEFAULT_RAB_IS_AM False "set the RLC mode to AM for the d add_boolean_option(OAI_NW_DRIVER_TYPE_ETHERNET False "????") add_boolean_option(DISABLE_USE_NAS False "???") add_boolean_option(LOWLATENCY True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14") +add_boolean_option(CPU_AFFINITY False "Enable CPU Affinity of threads (only valid without deadline scheduler). It is enabled only with >2 CPUs") add_boolean_option(NAS_ADDRESS_FIX False "specific to oaisim: for nasmesh driver") add_boolean_option(NAS_NETLINK False "???? Must be True to compile nasmesh driver without rtai") add_boolean_option(OAISIM False "specific to oaisim") diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 0f4e43e5293c43a01a528b088a162cbe91ef6dff..08d66533d38b7e005fe1bd537671370765a4b4a8 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -47,6 +47,7 @@ PRINT_STATS="False" VCD_TIMING="False" LOWLATENCY_FLAG_USER="False" FORCE_LOWLATENCY_FLAG_USER="" +CPU_AFFINITY_FLAG_USER="True" #Only valid when lowlatecy flag is set to False REL="Rel10" HW="None" TP="None" @@ -125,6 +126,8 @@ Options Disables deadline scheduler of Linux kernel (>=3.14.x). --enable-deadline Disables deadline scheduler of Linux kernel (>=3.14.x). +--disable-cpu-affinity + Enables CPU Affinity between UHD/TX/RX Threads (Valid only when deadline scheduler is disabled). By defaulT, CPU Affinity is enabled when not using deadline scheduler. It is enabled only with >2 CPUs. For eNB, CPU_0-> Device library (UHD), CPU_1->TX Threads, CPU_2...CPU_MAX->Rx Threads. For UE, CPU_0->Device Library(UHD), CPU_1..CPU_MAX -> All the UE threads Usage (first build): oaisim (eNB + UE): ./build_oai -I -g --oaisim -x --install-system-files Eurecom EXMIMO + COTS UE : ./build_oai -I -g --eNB -x --install-system-files @@ -263,6 +266,10 @@ function main() { FORCE_LOWLATENCY_FLAG_USER="True" echo_info "Enabling the usage of deadline scheduler" shift 1;; + --disable-cpu-affinity) + CPU_AFFINITY_FLAG_USER="False" + echo_info "Disabling CPU Affinity (only valid when not using deadline scheduler)" + shift 1;; -h | --help) print_help exit 1;; @@ -328,8 +335,13 @@ function main() { LOWLATENCY_FLAG_USER=$FORCE_LOWLATENCY_FLAG_USER fi - echo_info "Flags for Deadline scheduler: $LOWLATENCY_FLAG_USER" + #Disable CPU Affinity for deadline scheduler + if [ "$LOWLATENCY_FLAG_USER" = "True" ] ; then + CPU_AFFINITY_FLAG_USER="False" + fi + echo_info "Flags for Deadline scheduler: $LOWLATENCY_FLAG_USER" + echo_info "Flags for CPU Affinity: $CPU_AFFINITY_FLAG_USER" ############################################ # setting and printing OAI envs, we should check here @@ -421,6 +433,7 @@ function main() { echo "set ( TRANSP_PRO \"${TP}\")" >> $cmake_file echo "set(PACKAGE_NAME \"${lte_exec}\")" >> $cmake_file echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )" >>$cmake_file + echo "set (CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >>$cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$lte_build_dir/build cmake .. @@ -648,6 +661,7 @@ function main() { echo "set(TRANSP_PRO \"${TP}\")" >> $cmake_file echo 'set(PACKAGE_NAME "\"rrh_gw\"")' >> $cmake_file echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )" >>$cmake_file + echo "set (CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >>$cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$rrh_build_dir/build cmake .. diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index af09d715f5f18a2f5b1ff5f95bc275680867cdee..b08b73788b61333ebfa071d1f49cd60cca50df61 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1121,6 +1121,8 @@ static void* eNB_thread_tx( void* param ) /* CPU 1 is reserved for all TX threads */ /* Enable CPU Affinity only if number of CPUs >2 */ CPU_ZERO(&cpuset); + + #ifdef CPU_AFFINITY if (get_nprocs() > 2) { CPU_SET(1, &cpuset); @@ -1131,6 +1133,7 @@ static void* eNB_thread_tx( void* param ) exit_fun("Error setting processor affinity"); } } + #endif /* Check the actual affinity mask assigned to the thread */ @@ -1401,6 +1404,7 @@ static void* eNB_thread_rx( void* param ) /* CPU 2..MAX_CPUS is reserved for all RX threads */ /* Set CPU Affinity only if number of CPUs >2 */ CPU_ZERO(&cpuset); + #ifdef CPU_AFFINITY if (get_nprocs() >2) { for (j = 2; j < get_nprocs(); j++) @@ -1413,7 +1417,7 @@ static void* eNB_thread_rx( void* param ) exit_fun (" Error setting processor affinity :"); } } - + #endif /* Check the actual affinity mask assigned to the thread */ s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); @@ -1788,12 +1792,6 @@ static void* eNB_thread( void* arg ) attr.sched_deadline = (0.9 * 100) * 10000; attr.sched_period = 1 * 1000000; - - /* pin the eNB main thread to CPU0*/ - /* if (pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask) <0) { - perror("[MAIN_ENB_THREAD] pthread_setaffinity_np failed\n"); - }*/ - if (sched_setattr(0, &attr, flags) < 0 ) { perror("[SCHED] main eNB thread: sched_setattr failed\n"); exit_fun("Nothing to add"); @@ -1812,15 +1810,21 @@ static void* eNB_thread( void* arg ) /* Set affinity mask to include CPUs 1 to MAX_CPUS */ /* CPU 0 is reserved for UHD threads */ CPU_ZERO(&cpuset); - for (j = 1; j < get_nprocs(); j++) + #ifdef CPU_AFFINITY + if (get_nprocs() >2) + { + for (j = 1; j < get_nprocs(); j++) CPU_SET(j, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) + { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } } + #endif + /* Check the actual affinity mask assigned to the thread */ s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); @@ -3303,43 +3307,43 @@ int main( int argc, char **argv ) #ifndef LOWLATENCY /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */ + + cpu_set_t cpuset; + int s; + char cpu_affinity[1024]; + CPU_ZERO(&cpuset); + #ifdef CPU_AFFINITY if (get_nprocs() > 2) { - cpu_set_t cpuset; - int s; - char cpu_affinity[1024]; - - LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n"); - - CPU_ZERO(&cpuset); CPU_SET(0, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); if (s != 0) { perror( "pthread_setaffinity_np"); exit_fun("Error setting processor affinity"); } + LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n"); + } + #endif - /* Check the actual affinity mask assigned to the thread */ - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (int j = 0; j < CPU_SETSIZE; j++) - { - if (CPU_ISSET(j, &cpuset)) - { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } + /* Check the actual affinity mask assigned to the thread */ + s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) + { + perror( "pthread_getaffinity_np"); + exit_fun("Error getting processor affinity "); + } + memset(cpu_affinity, 0 , sizeof(cpu_affinity)); + for (int j = 0; j < CPU_SETSIZE; j++) + { + if (CPU_ISSET(j, &cpuset)) + { + char temp[1024]; + sprintf(temp, " CPU_%d ", j); + strcat(cpu_affinity, temp); } - LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); } + LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); #endif /* device host type is set*/ @@ -3524,17 +3528,6 @@ int main( int argc, char **argv ) pthread_cond_init(&sync_cond,NULL); pthread_mutex_init(&sync_mutex, NULL); - /* this is moved to the eNB main thread */ - -//#if defined(ENABLE_ITTI) - // Wait for eNB application initialization to be complete (eNB registration to MME) - // if (UE_flag==0) { - // printf("Waiting for eNB application to be ready\n"); - //wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB); - // } - //#endif - - // this starts the DMA transfers #ifdef EXMIMO diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 03871e865b0344a693dfed854ece3a067ecff1f7..561554516cd242e818ec6e53bbf97773ff0bb69a 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -221,15 +221,22 @@ static void *UE_thread_synch(void *arg) /* Set affinity mask to include CPUs 1 to MAX_CPUS */ /* CPU 0 is reserved for UHD threads */ CPU_ZERO(&cpuset); - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) + #ifdef CPU_AFFINITY + if (get_nprocs() >2) { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); + for (j = 1; j < get_nprocs(); j++) + CPU_SET(j, &cpuset); + + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) + { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } } + #endif + /* Check the actual affinity mask assigned to the thread */ s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); @@ -724,15 +731,22 @@ static void *UE_thread_tx(void *arg) /* Set affinity mask to include CPUs 1 to MAX_CPUS */ /* CPU 0 is reserved for UHD threads */ CPU_ZERO(&cpuset); - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) + #ifdef CPU_AFFINITY + if (get_nprocs() >2) { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); + for (j = 1; j < get_nprocs(); j++) + CPU_SET(j, &cpuset); + + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) + { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } } + #endif + /* Check the actual affinity mask assigned to the thread */ s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); @@ -935,15 +949,22 @@ static void *UE_thread_rx(void *arg) /* Set affinity mask to include CPUs 1 to MAX_CPUS */ /* CPU 0 is reserved for UHD threads */ CPU_ZERO(&cpuset); - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) + #ifdef CPU_AFFINITY + if (get_nprocs() >2) { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); + for (j = 1; j < get_nprocs(); j++) + CPU_SET(j, &cpuset); + + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) + { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } } + #endif + /* Check the actual affinity mask assigned to the thread */ s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);