From patchwork Mon Sep 26 08:35:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: jozmarti@cisco.com X-Patchwork-Id: 16110 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 503DE475E; Mon, 26 Sep 2016 10:35:14 +0200 (CEST) Received: from aer-iport-3.cisco.com (aer-iport-3.cisco.com [173.38.203.53]) by dpdk.org (Postfix) with ESMTP id 9719237B4 for ; Mon, 26 Sep 2016 10:35:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=5116; q=dns/txt; s=iport; t=1474878912; x=1476088512; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=kbCigCTQHX/Hc+t8w3YT1UV4BWKeRFzvxbx4l8S+kzA=; b=Lk0YQfJLv9Q0YptUgjY/ipNqPp3n13vAVub04GR9gwiOLrZpIw/Bppy9 jPC+CTYdyHWpD4cOimLwy/CXTYxFgAPVrCNbJY4qns/R129bQq9B3wcIR oGKwuLRGqam2o292qvXxqJReGqqWY3rFbiTQ9UChD8Awz0uQXoOtk3LXy E=; X-IronPort-AV: E=Sophos;i="5.30,398,1470700800"; d="scan'208";a="646974576" Received: from aer-iport-nat.cisco.com (HELO aer-core-3.cisco.com) ([173.38.203.22]) by aer-iport-3.cisco.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Sep 2016 08:35:11 +0000 Received: from localhost.localdomain (dhcp-10-61-101-93.cisco.com [10.61.101.93]) by aer-core-3.cisco.com (8.14.5/8.14.5) with ESMTP id u8Q8ZBgl031282; Mon, 26 Sep 2016 08:35:11 GMT From: jozmarti@cisco.com To: dev@dpdk.org Cc: Jozef Martiniak Date: Mon, 26 Sep 2016 10:35:09 +0200 Message-Id: <1474878909-15534-1-git-send-email-jozmarti@cisco.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1469016644-6521-1-git-send-email-jozmarti@cisco.com> References: <1469016644-6521-1-git-send-email-jozmarti@cisco.com> Subject: [dpdk-dev] [PATCH v3] rte_delay_us can be replaced with user function X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Jozef Martiniak When running single-core, some drivers tend to call rte_delay_us for a long time, and that is causing packet drops. To avoid this, rte_delay_us can be replaced with user-defined delay function with: void rte_delay_us_callback_register(void(*userfunc)(unsigned)); When userfunc==rte_delay_us_block build-in blocking delay function is restored. Signed-off-by: Jozef Martiniak --- app/test/test_cycles.c | 45 ++++++++++++++++++++++ lib/librte_eal/bsdapp/eal/rte_eal_version.map | 8 ++++ lib/librte_eal/common/eal_common_timer.c | 17 +++++++- lib/librte_eal/common/include/generic/rte_cycles.h | 22 ++++++++++- lib/librte_eal/linuxapp/eal/rte_eal_version.map | 8 ++++ 5 files changed, 97 insertions(+), 3 deletions(-) diff --git a/app/test/test_cycles.c b/app/test/test_cycles.c index f6c043a..f189797 100644 --- a/app/test/test_cycles.c +++ b/app/test/test_cycles.c @@ -90,3 +90,48 @@ test_cycles(void) } REGISTER_TEST_COMMAND(cycles_autotest, test_cycles); + +/* + * rte_delay_us_callback test + * + * - check if callback is correctly registered/unregistered + * + */ + +static unsigned int pattern; +static void my_rte_delay_us(unsigned int us) +{ + pattern += us; +} + +static int +test_user_delay_us(void) +{ + pattern = 0; + + rte_delay_us(2); + if (pattern != 0) + return -1; + + /* register custom delay function */ + rte_delay_us_callback_register(my_rte_delay_us); + + rte_delay_us(2); + if (pattern != 2) + return -1; + + rte_delay_us(3); + if (pattern != 5) + return -1; + + /* restore original delay function */ + rte_delay_us_callback_register(rte_delay_us_block); + + rte_delay_us(3); + if (pattern != 5) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(user_delay_us, test_user_delay_us); diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map index a335e04..a06acc1 100644 --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map @@ -162,3 +162,11 @@ DPDK_16.07 { rte_thread_setname; } DPDK_16.04; + +DPDK_16.11 { + global: + + rte_delay_us_block; + rte_delay_us_callback_register; + +} DPDK_16.07; diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c index c4227cd..7265617 100644 --- a/lib/librte_eal/common/eal_common_timer.c +++ b/lib/librte_eal/common/eal_common_timer.c @@ -47,8 +47,11 @@ /* The frequency of the RDTSC timer resolution */ static uint64_t eal_tsc_resolution_hz; +/* Pointer to user delay function */ +void (*rte_delay_us)(unsigned int) = NULL; + void -rte_delay_us(unsigned us) +rte_delay_us_block(unsigned int us) { const uint64_t start = rte_get_timer_cycles(); const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6; @@ -84,3 +87,15 @@ set_tsc_freq(void) RTE_LOG(DEBUG, EAL, "TSC frequency is ~%" PRIu64 " KHz\n", freq / 1000); eal_tsc_resolution_hz = freq; } + +void rte_delay_us_callback_register(void (*userfunc)(unsigned int)) +{ + rte_delay_us = userfunc; +} + +static void __attribute__((constructor)) +rte_timer_init(void) +{ + /* set rte_delay_us_block as a delay function */ + rte_delay_us_callback_register(rte_delay_us_block); +} diff --git a/lib/librte_eal/common/include/generic/rte_cycles.h b/lib/librte_eal/common/include/generic/rte_cycles.h index 8cc21f2..96a2da9 100644 --- a/lib/librte_eal/common/include/generic/rte_cycles.h +++ b/lib/librte_eal/common/include/generic/rte_cycles.h @@ -180,15 +180,16 @@ rte_get_timer_hz(void) default: rte_panic("Invalid timer source specified\n"); } } - /** * Wait at least us microseconds. + * This function can be replaced with user-defined function. + * @see rte_delay_us_callback_register * * @param us * The number of microseconds to wait. */ void -rte_delay_us(unsigned us); +(*rte_delay_us)(unsigned int us); /** * Wait at least ms milliseconds. @@ -202,4 +203,21 @@ rte_delay_ms(unsigned ms) rte_delay_us(ms * 1000); } +/** + * Blocking delay function. + * + * @param us + * Number of microseconds to wait. + */ +void rte_delay_us_block(unsigned int us); + +/** + * Replace rte_delay_us with user defined function. + * + * @param userfunc + * User function which replaces rte_delay_us. rte_delay_us_block restores + * buildin block delay function. + */ +void rte_delay_us_callback_register(void(*userfunc)(unsigned int)); + #endif /* _RTE_CYCLES_H_ */ diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map index db8c984..db216cc 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -166,3 +166,11 @@ DPDK_16.07 { rte_thread_setname; } DPDK_16.04; + +DPDK_16.11 { + global: + + rte_delay_us_block; + rte_delay_us_callback_register; + +} DPDK_16.07;