From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Dumazet Subject: Re: [patch] pktgen: bug when calling ndelay in x86 architectures Date: Wed, 19 Oct 2011 12:13:55 +0200 Message-ID: <1319019235.3103.10.camel@edumazet-laptop> References: <4E9D5E1B.3080704@gmail.com> <1318939007.2657.57.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC> <1318946401.23980.6.camel@deadeye> <1318949264.2657.97.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC> <4E9E9963.7090209@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: Ben Hutchings , David Miller , netdev@vger.kernel.org, Robert Olsson , Voravit Tanyingyong , Jens Laas To: Daniel Turull Return-path: Received: from mail-bw0-f46.google.com ([209.85.214.46]:57262 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752106Ab1JSKOB (ORCPT ); Wed, 19 Oct 2011 06:14:01 -0400 Received: by bkbzt19 with SMTP id zt19so1899799bkb.19 for ; Wed, 19 Oct 2011 03:14:00 -0700 (PDT) In-Reply-To: <4E9E9963.7090209@gmail.com> Sender: netdev-owner@vger.kernel.org List-ID: Le mercredi 19 octobre 2011 =C3=A0 11:33 +0200, Daniel Turull a =C3=A9c= rit : > Hi, > then if we want to use the spin more often. > maybe we can increase the constant from 100000 (0.1ms) to 1000000 (1m= s)? > How was the current value chosen? >=20 Based on user needs ;) > I did some measurements of the inter-arrival time between packets > and with bigger values the maximal is reduced in the rates between > 2kpps and 20kpps. >=20 ndelay()/udelay() have some inaccuracies, for 'long' values, because of rounding errors. If we spin, just call ktime_now() in a loop until spin_until is reached... That way you get max possible resolution, given kernel time service constraints. Untested patch : diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 38d6577..5c7e900 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2145,9 +2145,11 @@ static void spin(struct pktgen_dev *pkt_dev, kti= me_t spin_until) } =20 start_time =3D ktime_now(); - if (remaining < 100000) - ndelay(remaining); /* really small just spin */ - else { + if (remaining < 100000) { + do { + end_time =3D ktime_now(); + } while (ktime_lt(end_time, spin_until)); + } else { /* see do_nanosleep */ hrtimer_init_sleeper(&t, current); do { @@ -2162,8 +2164,8 @@ static void spin(struct pktgen_dev *pkt_dev, ktim= e_t spin_until) hrtimer_cancel(&t.timer); } while (t.task && pkt_dev->running && !signal_pending(current)); __set_current_state(TASK_RUNNING); + end_time =3D ktime_now(); } - end_time =3D ktime_now(); =20 pkt_dev->idle_acc +=3D ktime_to_ns(ktime_sub(end_time, start_time)); pkt_dev->next_tx =3D ktime_add_ns(spin_until, pkt_dev->delay);