From patchwork Tue May 24 11:02:57 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Lutomirski X-Patchwork-Id: 811572 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter2.kernel.org (8.14.4/8.14.3) with ESMTP id p4OB8H6J004279 for ; Tue, 24 May 2011 11:08:38 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DE07A9EB22 for ; Tue, 24 May 2011 04:08:16 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Tue, 24 May 2011 11:08:38 +0000 (UTC) X-Greylist: delayed 301 seconds by postgrey-1.31 at gabe; Tue, 24 May 2011 04:08:06 PDT Received: from dmz-mailsec-scanner-3.mit.edu (DMZ-MAILSEC-SCANNER-3.MIT.EDU [18.9.25.14]) by gabe.freedesktop.org (Postfix) with ESMTP id 6F09A9E748 for ; Tue, 24 May 2011 04:08:06 -0700 (PDT) X-AuditID: 1209190e-b7c39ae000000a8c-57-4ddb90637c7d Received: from mailhub-auth-3.mit.edu ( [18.9.21.43]) by dmz-mailsec-scanner-3.mit.edu (Symantec Messaging Gateway) with SMTP id 86.C9.02700.4609BDD4; Tue, 24 May 2011 07:03:00 -0400 (EDT) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id p4OB34FN001292; Tue, 24 May 2011 07:03:04 -0400 Received: from antithesis.localdomain (207-172-69-77.c3-0.smr-ubr3.sbo-smr.ma.static.cable.rcn.com [207.172.69.77]) (authenticated bits=0) (User authenticated as luto@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id p4OB2xFN028272 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 24 May 2011 07:03:02 -0400 (EDT) Message-ID: <4DDB9061.3030502@mit.edu> Date: Tue, 24 May 2011 07:02:57 -0400 From: Andy Lutomirski User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc15 Thunderbird/3.1.10 MIME-Version: 1.0 Newsgroups: gmane.comp.video.dri.devel, gmane.comp.freedesktop.xorg.drivers.intel To: Daniel J Blueman Subject: Re: [2.6.39-rc7] i915: kworker busily spinning... References: In-Reply-To: X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprHKsWRmVeSWpSXmKPExsUixCmqrZsy4bavwf//TBZXby1gsrj58Cyr xbvz6xktrnx9z2Yxe8JmJgdWj5UftDx2zrrL7nG/+ziTx/t9V9kCWKK4bFJSczLLUov07RK4 Mjo2bmItaDCpON+5mrGBsU27i5GTQ0LARGLZk5fMELaYxIV769m6GLk4hAT2MUrcO3mGGcLZ wChx4fh1FgjnM5PEsrddYC28AmoSb9b+YQOxWQRUJU69WAdmswmoSHQsfcAEYosKVEpM+rmD FaJeUOLkzCcsIDafQIDE1jP/wOIiAvoST358B1vNLDCDUaLzyl2wImEBK4l1/46BFQkJOEg8 nb0VbCingKPErL6bjCA2s4COxLu+B8wQtrzE9rdzmCcwCs1Csm8WkrJZSMoWMDKvYpRNya3S zU3MzClOTdYtTk7My0st0jXWy80s0UtNKd3ECI4GSb4djF8PKh1iFOBgVOLh9Zl+y1eINbGs uDL3EKMkB5OSKO/entu+QnxJ+SmVGYnFGfFFpTmpxYcYJTiYlUR4V2QB5XhTEiurUovyYVLS HCxK4rwzJdV9hQTSE0tSs1NTC1KLYLIyHBxKErwJ/UCNgkWp6akVaZk5JQhpJg5OkOE8QMMb QWp4iwsSc4sz0yHypxgVpcR500ASAiCJjNI8uF5YsnrFKA70ijBvGUgVDzDRwXW/AhrMBDRY 4u9NkMEliQgpqQbGBRo9c8Nv/dr5MfN/YL6Z1+wVEYJnL/275Wt90Cm9Yfqhtc2Xasst9VZ+ Mu8s2Putyv+CQf6dz/m7nP4cePRqg0zw9X7FuLLNghsPKcyexTA/JnNXcMTGhecvRpd9uax9 S7i7+2eZeb1+Wvja3+46bCeuKsw1Xv61WYT7k1m+icf6OYnCLRublFiKMxINtZiLihMBcj1l PTEDAAA= Cc: Dave Airlie , intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org On 05/17/2011 07:27 AM, Daniel J Blueman wrote: > With 2.6.39-rc7 on my Sandy Bridge laptop GPU (8086:0126 rev 9), > sometimes I find one of the kworker threads busily running with 15-20% > system time for some minutes, causing terrible interactivity latency. > I've seen it occur when plugging eg a HDMI display, and also when no > display has been plugged (ie only the internal LVDS connection is > active). > > Across multiple kernel task captures, I see the kernel thread > consistently reading one of the connector's EDID data [1]; I guess > either it's having a hard time reading from a disconnected connector > and retrying, or is incorrectly detecting a change when there is none. > > I'll enable DRM debugging to see what connectors it believes it needs > to read from. Anything else that would be handy to capture, or any > thoughts? > > Also, the 100ms connector change polling seems overkill, particularly > when power consumption is important; 1000-2000ms would be sufficient, > do you think? I think it's meant to be every 10 seconds. In any case, the output_poll_execute code does more work than necessary, which might exacerbate the problem. Here's an old patch I wrote that probably doesn't apply any more but might help. commit 82c9114cdc60aba7d9bec1396d818362a208cfdc Author: Andy Lutomirski Date: Tue Aug 17 09:38:59 2010 -0400 drm: Try to poll fewer unnecessary outputs We used to poll all outputs that had any kind of polling enabled every time that the output polling work ran (i.e. every ten seconds). Now only poll hotplug-interrupt capable outputs when hotplug is detected and we only poll POLL_CONNECT and POLL_DISCONNECT when in the appropriate state. Signed-off-by: Andy Lutomirski --Andy > > Thanks, > Daniel > > --- [1] > > kworker/2:2 R running task 5048 86 2 0x00000000 > 0000000000000002 ffff88021e804040 ffff88021e85f9b0 ffff88021e804040 > ffff88021e85e000 0000000000004000 ffff8802210a4040 ffff88021e804040 > 0000000000000046 ffffffff81c18b20 ffff88022106c000 ffffffff8270b740 > Call Trace: > [] ? mark_held_locks+0x70/0xa0 > [] ? get_parent_ip+0x11/0x50 > [] ? sub_preempt_count+0x9d/0xd0 > [] schedule_timeout+0x175/0x250 > [] ? run_timer_softirq+0x2a0/0x2a0 > [] schedule_timeout_uninterruptible+0x19/0x20 > [] msleep+0x18/0x20 > [] gmbus_xfer+0x400/0x620 [i915] > [] i2c_transfer+0xa2/0xf0 > [] drm_do_probe_ddc_edid+0x66/0xa0 [drm] > [] drm_get_edid+0x29/0x60 [drm] > [] intel_hdmi_detect+0x56/0xe0 [i915] > [] output_poll_execute+0xd7/0x1a0 [drm_kms_helper] > [] process_one_work+0x1a4/0x450 > [] ? process_one_work+0x146/0x450 > [] ? > drm_helper_disable_unused_functions+0x150/0x150 [drm_kms_helper] > [] process_scheduled_works+0x2c/0x40 > [] worker_thread+0x284/0x350 > [] ? manage_workers.clone.23+0x120/0x120 > [] kthread+0xb6/0xc0 > [] ? trace_hardirqs_on_caller+0x13d/0x180 > [] kernel_thread_helper+0x4/0x10 > [] ? finish_task_switch+0x6f/0x100 > [] ? retint_restore_args+0xe/0xe > [] ? __init_kthread_worker+0x70/0x70 > [] ? gs_change+0xb/0xb diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 9b2a541..5a39e3c 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -817,31 +817,38 @@ static void output_poll_execute(struct slow_work *work) struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_slow_work); struct drm_connector *connector; enum drm_connector_status old_status, status; - bool repoll = false, changed = false; + bool repoll = false, changed = false, need_poll, hpd_detected; int ret; + hpd_detected = ACCESS_ONCE(dev->mode_config.hpd_detected); + ACCESS_ONCE(dev->mode_config.hpd_detected) = 0; + mutex_lock(&dev->mode_config.mutex); list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - /* if this is HPD or polled don't check it - - TV out for instance */ + /* don't poll unless the drivers asked us to. */ if (!connector->polled) continue; - else if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT)) - repoll = true; + /* poll if we got an HPD request... */ + need_poll = hpd_detected; + /* ...or if we're supposed to poll all the time */ old_status = connector->status; - /* if we are connected and don't want to poll for disconnect - skip it */ - if (old_status == connector_status_connected && - !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT) && - !(connector->polled & DRM_CONNECTOR_POLL_HPD)) - continue; + if (old_status == connector_status_connected ? + (connector->polled & DRM_CONNECTOR_POLL_CONNECT) : + (connector->polled & DRM_CONNECTOR_POLL_DISCONNECT)) + need_poll = true; - status = connector->funcs->detect(connector); - if (old_status != status) - changed = true; + /* Do we re-queue? */ + if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT)) + repoll = true; + + if (need_poll) { + status = connector->funcs->detect(connector); + if (old_status != status) + changed = true; + } } mutex_unlock(&dev->mode_config.mutex); @@ -911,6 +918,7 @@ void drm_helper_hpd_irq_event(struct drm_device *dev) return; delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); /* schedule a slow work asap */ + ACCESS_ONCE(dev->mode_config.hpd_detected) = true; delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0); } EXPORT_SYMBOL(drm_helper_hpd_irq_event); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 93a1a31..586f41f 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -596,6 +596,7 @@ struct drm_mode_config { /* output poll support */ bool poll_enabled; struct delayed_slow_work output_poll_slow_work; + bool hpd_detected; /* pointers to standard properties */ struct list_head property_blob_list;