From owner-svn-src-head@freebsd.org Wed Mar 28 17:39:24 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A04E2F6DD82; Wed, 28 Mar 2018 17:39:24 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 273AB79B48; Wed, 28 Mar 2018 17:39:24 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D4CA96219; Wed, 28 Mar 2018 17:39:23 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w2SHdNvL094041; Wed, 28 Mar 2018 17:39:23 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w2SHdNtK094040; Wed, 28 Mar 2018 17:39:23 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201803281739.w2SHdNtK094040@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Wed, 28 Mar 2018 17:39:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r331692 - head/sys/dev/usb/input X-SVN-Group: head X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: head/sys/dev/usb/input X-SVN-Commit-Revision: 331692 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Mar 2018 17:39:24 -0000 Author: hselasky Date: Wed Mar 28 17:39:23 2018 New Revision: 331692 URL: https://svnweb.freebsd.org/changeset/base/331692 Log: Fix for regression issue in USB keyboard driver after r304735. A series of zero delay callouts can happen causing high CPU usage of the timer subsystem when trying to repeat keys, because the time of the absolute timeout is not moving forward. The condition clears when all keys are released. Reported by: Johannes Lundberg Discussed with: bde@ PR: 226968 MFC after: 1 week Sponsored by: Mellanox Technologies Modified: head/sys/dev/usb/input/ukbd.c Modified: head/sys/dev/usb/input/ukbd.c ============================================================================== --- head/sys/dev/usb/input/ukbd.c Wed Mar 28 17:19:04 2018 (r331691) +++ head/sys/dev/usb/input/ukbd.c Wed Mar 28 17:39:23 2018 (r331692) @@ -386,10 +386,22 @@ ukbd_any_key_pressed(struct ukbd_softc *sc) static void ukbd_start_timer(struct ukbd_softc *sc) { - sbintime_t delay, prec; + sbintime_t delay, now, prec; + now = sbinuptime(); + + /* check if initial delay passed and fallback to key repeat delay */ + if (sc->sc_delay == 0) + sc->sc_delay = sc->sc_kbd.kb_delay2; + + /* compute timeout */ delay = SBT_1MS * sc->sc_delay; sc->sc_co_basetime += delay; + + /* check if we are running behind */ + if (sc->sc_co_basetime < now) + sc->sc_co_basetime = now; + /* This is rarely called, so prefer precision to efficiency. */ prec = qmin(delay >> 7, SBT_1MS * 10); usb_callout_reset_sbt(&sc->sc_callout, sc->sc_co_basetime, prec, @@ -510,7 +522,6 @@ ukbd_get_key(struct ukbd_softc *sc, uint8_t wait) static void ukbd_interrupt(struct ukbd_softc *sc) { - struct timeval ctv; uint32_t n_mod; uint32_t o_mod; uint32_t now = sc->sc_time_ms; @@ -580,14 +591,11 @@ rfound: ; break; } } - if (j < UKBD_NKEYCODE) { - /* Old key repeating. */ - sc->sc_delay = sc->sc_kbd.kb_delay2; - } else { - /* New key. */ - microuptime(&ctv); - sc->sc_co_basetime = tvtosbt(ctv); + if (j == UKBD_NKEYCODE) { + /* New key - set initial delay and [re]start timer */ + sc->sc_co_basetime = sbinuptime(); sc->sc_delay = sc->sc_kbd.kb_delay1; + ukbd_start_timer(sc); } ukbd_put_key(sc, key | KEY_PRESS); @@ -837,10 +845,6 @@ ukbd_intr_callback(struct usb_xfer *xfer, usb_error_t } ukbd_interrupt(sc); - - if (ukbd_any_key_pressed(sc) != 0) { - ukbd_start_timer(sc); - } case USB_ST_SETUP: tr_setup: