From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 44E7D4A63 for ; Wed, 3 Jun 2015 14:54:14 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 03 Jun 2015 05:54:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,547,1427785200"; d="scan'208";a="720011533" Received: from bricha3-mobl3.ger.corp.intel.com ([10.243.20.22]) by fmsmga001.fm.intel.com with SMTP; 03 Jun 2015 05:54:11 -0700 Received: by (sSMTP sendmail emulation); Wed, 03 Jun 2015 13:54:10 +0025 Date: Wed, 3 Jun 2015 13:54:10 +0100 From: Bruce Richardson To: Selmon Yang Message-ID: <20150603125410.GA5880@bricha3-MOBL3> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Organization: Intel Shannon Ltd. User-Agent: Mutt/1.5.23 (2014-03-12) Cc: dev@dpdk.org Subject: Re: [dpdk-dev] rte_eal_alarm_set() is affected by discontinuous jumps in the system time 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: , X-List-Received-Date: Wed, 03 Jun 2015 12:54:15 -0000 On Wed, Jun 03, 2015 at 02:31:47PM +0800, Selmon Yang wrote: > Hi, > > I found that, in dpdk 2.0, rte_eal_alarm_set() is affected by > discontinuous jumps in the system time because eal_alarm_callback() > and rte_eal_alarm_set() use gettimeofday() to get the current time. > > Here is what I encountered. > I set up a rte eal alarm as below, and I like it to be triggered every second. > #define USE_PER_S 1000 * 1000 > void my_alarm_cb(void *arg) > { > /* send heartbeat signal out, etc. */ > > rte_eal_alarm_set(1 * US_PER_S, my_alarm_cb, NULL); > return; > } > > int main(void) > { > /* ..., do something */ > rte_eal_alarm_set(1 * US_PER_S, my_alarm_cb, NULL); > /* ... do something else */ > } > > It works fine in most of time. > However, if I change system time manually, it is possible that rte alarm > function works out of my expectation. > Suppose that current time is 11:00:00 AM, and eal_alarm_callback() > is triggered because I executed > rte_eal_alarm_set(1 * US_PER_S, my_alarm_cb, NULL) at 10:59:59 AM. > eal_alarm_callback() gets the current time (11:00:00 AM) > and calls my_alarm_cb() as below. > while ((ap = LIST_FIRST(&alarm_list)) !=NULL && > gettimeofday(&now, NULL) == 0 && > (ap->time.tv_sec < now.tv_sec || > (ap->time.tv_sec == now.tv_sec && > ap->time.tv_usec <= > now.tv_usec))){ > ap->executing = 1; > ap->executing_id = pthread_self(); > rte_spinlock_unlock(&alarm_list_lk); > > ap->cb_fn(ap->cb_arg); > > rte_spinlock_lock(&alarm_list_lk); > > LIST_REMOVE(ap, next); > rte_free(ap); > } > > In my_alarm_cb(), rte_eal_alarm_set() is called again. > rte_eall_alarm_set() gets the current time (11:00:00 AM), plus 1 second, > and adds the new alarm entry to alarm_list. > /* use current time to calculate absolute time of alarm */ > gettimeofday(&now, NULL); > > new_alarm->cb_fn = cb_fn; > new_alarm->cb_arg = cb_arg; > new_alarm->time.tv_usec = (now.tv_usec + us) % US_PER_S; > new_alarm->time.tv_sec = now.tv_sec + ((now.tv_usec + us) / US_PER_S); > > rte_spinlock_lock(&alarm_list_lk); > if (!handler_registered) { > ret |= rte_intr_callback_register(&intr_handle, > eal_alarm_callback, NULL); > handler_registered = (ret == 0) ? 1 : 0; > } > > if (LIST_EMPTY(&alarm_list)) > LIST_INSERT_HEAD(&alarm_list, new_alarm, next); > else { > LIST_FOREACH(ap, &alarm_list, next) { > if (ap->time.tv_sec > new_alarm->time.tv_sec || > (ap->time.tv_sec == > new_alarm->time.tv_sec && > > ap->time.tv_usec > new_alarm->time.tv_usec)){ > LIST_INSERT_BEFORE(ap, new_alarm, next); > break; > } > if (LIST_NEXT(ap, next) == NULL) { > LIST_INSERT_AFTER(ap, new_alarm, next); > break; > } > } > } > > After the new alarm entry is added to alarm_list, if current time is > set to 8:00:00 AM manually, the current time in eal_alarm_callback() > will be updated to 8:00:00 AM, too. > Then the new alarm entry will be triggered after 3 hours and 1 second. > > I think rte alarm should not be affected by discontinuous jumps in > the system time. > I tried to replace gettimeofday() with clock_gettime(CLOCK_MONOTONIC_RAW, &now), > and it looks work fine. > What do you think about this modification? > Will you consider to modify rte_alarm functions to be not affected > by discontinuous jumps in the system time? I agree with you that the alarm functionality should not be affected by jumps in system time. If you have a patch that fixes this bug, it would be great if you could upstream it here. Thanks, /Bruce