From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752698Ab0DMTj5 (ORCPT ); Tue, 13 Apr 2010 15:39:57 -0400 Received: from cpoproxy1-pub.bluehost.com ([69.89.21.11]:37125 "HELO outbound-mail-01.bluehost.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1752530Ab0DMTjy convert rfc822-to-8bit (ORCPT ); Tue, 13 Apr 2010 15:39:54 -0400 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=virtuousgeek.org; h=Received:Date:From:To:Cc:Subject:Message-ID:In-Reply-To:References:X-Mailer:Mime-Version:Content-Type:Content-Transfer-Encoding:X-Identified-User; b=puBR3F9A2BwkTi2m58oTCX5hJSBuEwixEBe9bAWi52qu2tuzM32nvUdocf0xsHQTcO4+rTJTYjJNjuOqwKQNt9YrGeKdT8i364ywl81j7WdWPgwhTn2+fVlbrRKKOHN7; Date: Tue, 13 Apr 2010 12:40:17 -0700 From: Jesse Barnes To: Pavel Machek Cc: linux-kernel@vger.kernel.org, intel-gfx@lists.freedesktop.org, Matthew Garrett Subject: Re: [PATCH 2/2] x86 platform driver: intelligent power sharing driver Message-ID: <20100413124017.40178399@virtuousgeek.org> In-Reply-To: <20100413192453.GB9548@ucw.cz> References: <1269646146-13296-1-git-send-email-jbarnes@virtuousgeek.org> <1269646146-13296-3-git-send-email-jbarnes@virtuousgeek.org> <20100413192453.GB9548@ucw.cz> X-Mailer: Claws Mail 3.7.5 (GTK+ 2.18.9; x86_64-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT X-Identified-User: {10642:box514.bluehost.com:virtuous:virtuousgeek.org} {sentby:smtp auth 75.110.194.140 authed with jbarnes@virtuousgeek.org} Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, 13 Apr 2010 21:24:53 +0200 Pavel Machek wrote: > Hi! > > > Intel Core i3/5 platforms with integrated graphics support both CPU and > > GPU turbo mode. CPU turbo mode is opportunistic: the CPU will use any > > available power to increase core frequencies if thermal headroom is > > available. The GPU side is more manual however; the graphics driver > > must monitor GPU power and temperature and coordinate with a core > > thermal driver to take advantage of available thermal and power headroom > > in the package. > > Interesting... > > > + * Copyright Š 2009-2010 Intel Corporation > > AC? Bad character set I guess. I'll just change it to (c). > > > + * The basic algorithm is driven by a 5s moving average of tempurature. If > > + * thermal headroom is available, the CPU and/or GPU power clamps may be > > + * adjusted upwards. If we hit the thermal ceiling or a thermal trigger, > > + * we scale back the clamp. Aside from trigger events (when we're critically > > + * close or over our TDP) we don't adjust the clamps more than once every > > + * five seconds. > > Ok, if this driver screws up will > > a) cpu/gpu protect itself from damage by overheat? > > b) cpu/gpu protect itself from incorrect operation resulting from > overtemp? The CPU will end up throttling itself, reducing performance to keep within its power budget. The GPU will just end up hanging if it overheats, but shouldn't be damaged. > > > + * Related documents: > > + * - CDI 403777, 403778 - Auburndale EDS vol 1 & 2 > > + * - CDI 401376 - Ibex Peak EDS > > + * - ref 26037, 26641 - IPS BIOS spec > > + * - ref 26489 - Nehalem BIOS writer's guide > > + * - ref 26921 - Ibex Peak BIOS Specification > > http references would be nice. They would be, but these docs are only available under NDA. If you have a sales or technical contact you can use the numbers here to get the right docs. > return (averun > 1); ? > > But this is wrong test, anyway. One process waiting for disk, and you > have D state and load average > 1, without cpu load. Yes, I'm happy to have a better test here. Not that it matters *too* much though; we'll allocate more power budget to the CPU, but it will only use it if needed. Allocating it more power just gives the turbo boost capability additional frequency bins. The CPU won't actually use those bins unless it detects that it can and will provide some benefit. > > > +/** > > + * ips_enable_cpu_turbo - enable turbo mode on all CPUs > > + * @ips: IPS driver struct > > + * > > + * Enable turbo mode by clearing the disable bit in IA32_PERF_CTL on > > + * all logical threads. > > + */ > > +static void ips_enable_cpu_turbo(struct ips_driver *ips) > > +{ > > + /* Already on, no need to mess with MSRs */ > > + if (ips->__cpu_turbo_on) > > + return; > > + > > + on_each_cpu(do_enable_cpu_turbo, ips, 1); > > + > > + ips->__cpu_turbo_on = true; > > +} > > + > > +/** > > + * do_disable_cpu_turbo - internal turbo disable function > > + * @data: unused > > + * > > + * Internal function for actually updating MSRs. When we enable/disable > > + * turbo, we need to do it on each CPU; this function is the one called > > + * by on_each_cpu() when needed. > > + */ > > +static void do_disable_cpu_turbo(void *data) > > +{ > > + u64 perf_ctl; > > + > > + rdmsrl(IA32_PERF_CTL, perf_ctl); > > + if (!(perf_ctl & IA32_PERF_TURBO_DIS)) { > > + perf_ctl |= IA32_PERF_TURBO_DIS; > > + wrmsrl(IA32_PERF_CTL, perf_ctl); > > + } > > +} > > + > > +/** > > + * ips_disable_cpu_turbo - disable turbo mode on all CPUs > > + * @ips: IPS driver struct > > + * > > + * Disable turbo mode by setting the disable bit in IA32_PERF_CTL on > > + * all logical threads. > > + */ > > +static void ips_disable_cpu_turbo(struct ips_driver *ips) > > +{ > > + /* Already off, leave it */ > > + if (!ips->__cpu_turbo_on) > > + return; > > + > > + on_each_cpu(do_disable_cpu_turbo, ips, 1); > > + > > + ips->__cpu_turbo_on = false; > > +} > > Merge above four functions into two, by having 'enable' parameter? > > Wha tprotects you against races? Accesses to these should be protected by the parameter lock. And I have two variables to differentiate between the hardware being enabled vs. the software requesting an enable/disable. They could probably be named more clearly. > > +/** > > + * ips_gpu_busy - is GPU busy? > > + * @ips: IPS driver struct > > + * > > + * Check GPU for load to see whether we should increase its thermal budget. > > + * We need to call into the i915 driver in this case. > > + * > > + * RETURNS: > > + * True if the GPU could use more power, false otherwise. > > + */ > > +static bool ips_gpu_busy(struct ips_driver *ips) > > +{ > > + return false; > > +} > > Uh ouch :-). This part is useless without the corresponding GPU power patch; that'll add the proper hooks and callbacks here. > > +/** > > + * mcp_exceeded - check whether we're outside our thermal & power limits > > + * @ips: IPS driver struct > > + * > > + * Check whether the MCP is over its thermal or power budget. > > + */ > > +static bool mcp_exceeded(struct ips_driver *ips) > > +{ > > + unsigned long flags; > > + bool ret = false; > > + > > + spin_lock_irqsave(&ips->turbo_status_lock, flags); > > + if (ips->mcp_avg_temp > (ips->mcp_temp_limit * 100)) > > + ret = true; > > + if (ips->cpu_avg_power + ips->mch_avg_power > ips->mcp_power_limit) > > + ret = true; > > + spin_unlock_irqrestore(&ips->turbo_status_lock, flags); > > + > > + return ret; > > +} > > ...and printk(kern_crit, as this should never happen?) Probably wouldn't hurt; but I've given myself some leeway here; if we're near the limit I'd like this check to return true and forcibly throttle things back, just to make extra sure we don't go over budget. On most standard voltage platforms this won't really matter, but on tightly designed ultra-low voltage platforms it's important we never hit the limit. > printk? > > Does this have hard limit for 2 cores? Yes, I don't believe we'll be doing 4 core Arrandale MCPs. And follow-on chips won't need this driver. > > > > +// if (ips->mch_avg_power > ips->mch_power_limit) > > +// ret = true; > > remove. > > > + dev_dbg(&ips->dev->dev, "starting ips-adjust thread\n"); > > + > > + /* > > + */ > > + do { > > ? What my blank comment wasn't clear? :) > > > +static u32 get_cpu_power(struct ips_driver *ips, u32 *last, int period) > > +{ > > + u32 val; > > + u32 ret; > > + > > + /* > > + * CEC is in joules/65535. Take difference over time to > > + * get watts. > > + */ > > + val = thm_readl(THM_CEC); > > + > > + /* period is in ms and we want mW */ > > + ret = (((val - *last) * 1000) / period); > > + ret = (ret * 1000) / 65535; > > + *last = val; > > + > > + return ret; > > +} > > I wonder if we should have milliwatt_t, msec_t and similar, to aid > with type checking... Yeah, keeping track of units better would be handy. > > > +static int show_cpu_temp(struct seq_file *m, void *data) > > +{ > > + struct ips_driver *ips = m->private; > > + > > + seq_printf(m, "%d.%d°C\n", ips->ctv1_avg_temp / 100, > > + ips->ctv1_avg_temp % 100); > > + > > + return 0; > > +} > > + > > Please no unicode at least in user interfaces. Ouch and it is subtly > wrong. You really want "%d.%02d". > > Ok, interesting. What kind of speedup can it bring? For the CPU the perf upside isn't that great, maybe 5% or so, and only with very specific workloads that take advantage of turbo boost. For graphics the upside is significant, at least 15% in my basic tests so far, but Eric and Keith have measured 3x gains in some cases. -- Jesse Barnes, Intel Open Source Technology Center From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jesse Barnes Subject: Re: [PATCH 2/2] x86 platform driver: intelligent power sharing driver Date: Tue, 13 Apr 2010 12:40:17 -0700 Message-ID: <20100413124017.40178399@virtuousgeek.org> References: <1269646146-13296-1-git-send-email-jbarnes@virtuousgeek.org> <1269646146-13296-3-git-send-email-jbarnes@virtuousgeek.org> <20100413192453.GB9548@ucw.cz> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from outbound-mail-01.bluehost.com (cpoproxy1-pub.bluehost.com [69.89.21.11]) by gabe.freedesktop.org (Postfix) with SMTP id 548B59E7B5 for ; Tue, 13 Apr 2010 12:39:54 -0700 (PDT) In-Reply-To: <20100413192453.GB9548@ucw.cz> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org To: Pavel Machek Cc: Matthew@freedesktop.org, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org List-Id: intel-gfx@lists.freedesktop.org T24gVHVlLCAxMyBBcHIgMjAxMCAyMToyNDo1MyArMDIwMApQYXZlbCBNYWNoZWsgPHBhdmVsQHVj dy5jej4gd3JvdGU6Cgo+IEhpIQo+IAo+ID4gSW50ZWwgQ29yZSBpMy81IHBsYXRmb3JtcyB3aXRo IGludGVncmF0ZWQgZ3JhcGhpY3Mgc3VwcG9ydCBib3RoIENQVSBhbmQKPiA+IEdQVSB0dXJibyBt b2RlLiAgQ1BVIHR1cmJvIG1vZGUgaXMgb3Bwb3J0dW5pc3RpYzogdGhlIENQVSB3aWxsIHVzZSBh bnkKPiA+IGF2YWlsYWJsZSBwb3dlciB0byBpbmNyZWFzZSBjb3JlIGZyZXF1ZW5jaWVzIGlmIHRo ZXJtYWwgaGVhZHJvb20gaXMKPiA+IGF2YWlsYWJsZS4gIFRoZSBHUFUgc2lkZSBpcyBtb3JlIG1h bnVhbCBob3dldmVyOyB0aGUgZ3JhcGhpY3MgZHJpdmVyCj4gPiBtdXN0IG1vbml0b3IgR1BVIHBv d2VyIGFuZCB0ZW1wZXJhdHVyZSBhbmQgY29vcmRpbmF0ZSB3aXRoIGEgY29yZQo+ID4gdGhlcm1h bCBkcml2ZXIgdG8gdGFrZSBhZHZhbnRhZ2Ugb2YgYXZhaWxhYmxlIHRoZXJtYWwgYW5kIHBvd2Vy IGhlYWRyb29tCj4gPiBpbiB0aGUgcGFja2FnZS4KPiAKPiBJbnRlcmVzdGluZy4uLgo+IAo+ID4g KyAqIENvcHlyaWdodCDDgsWgIDIwMDktMjAxMCBJbnRlbCBDb3Jwb3JhdGlvbgo+IAo+IEFDPwoK QmFkIGNoYXJhY3RlciBzZXQgSSBndWVzcy4gIEknbGwganVzdCBjaGFuZ2UgaXQgdG8gKGMpLgoK PiAKPiA+ICsgKiBUaGUgYmFzaWMgYWxnb3JpdGhtIGlzIGRyaXZlbiBieSBhIDVzIG1vdmluZyBh dmVyYWdlIG9mIHRlbXB1cmF0dXJlLiAgSWYKPiA+ICsgKiB0aGVybWFsIGhlYWRyb29tIGlzIGF2 YWlsYWJsZSwgdGhlIENQVSBhbmQvb3IgR1BVIHBvd2VyIGNsYW1wcyBtYXkgYmUKPiA+ICsgKiBh ZGp1c3RlZCB1cHdhcmRzLiAgSWYgd2UgaGl0IHRoZSB0aGVybWFsIGNlaWxpbmcgb3IgYSB0aGVy bWFsIHRyaWdnZXIsCj4gPiArICogd2Ugc2NhbGUgYmFjayB0aGUgY2xhbXAuICBBc2lkZSBmcm9t IHRyaWdnZXIgZXZlbnRzICh3aGVuIHdlJ3JlIGNyaXRpY2FsbHkKPiA+ICsgKiBjbG9zZSBvciBv dmVyIG91ciBURFApIHdlIGRvbid0IGFkanVzdCB0aGUgY2xhbXBzIG1vcmUgdGhhbiBvbmNlIGV2 ZXJ5Cj4gPiArICogZml2ZSBzZWNvbmRzLgo+IAo+IE9rLCBpZiB0aGlzIGRyaXZlciBzY3Jld3Mg dXAgd2lsbAo+IAo+IGEpIGNwdS9ncHUgcHJvdGVjdCBpdHNlbGYgZnJvbSBkYW1hZ2UgYnkgb3Zl cmhlYXQ/Cj4gCj4gYikgY3B1L2dwdSBwcm90ZWN0IGl0c2VsZiBmcm9tIGluY29ycmVjdCBvcGVy YXRpb24gcmVzdWx0aW5nIGZyb20KPiBvdmVydGVtcD8KClRoZSBDUFUgd2lsbCBlbmQgdXAgdGhy b3R0bGluZyBpdHNlbGYsIHJlZHVjaW5nIHBlcmZvcm1hbmNlIHRvIGtlZXAKd2l0aGluIGl0cyBw b3dlciBidWRnZXQuICBUaGUgR1BVIHdpbGwganVzdCBlbmQgdXAgaGFuZ2luZyBpZiBpdApvdmVy aGVhdHMsIGJ1dCBzaG91bGRuJ3QgYmUgZGFtYWdlZC4KCj4gCj4gPiArICogUmVsYXRlZCBkb2N1 bWVudHM6Cj4gPiArICogICAtIENESSA0MDM3NzcsIDQwMzc3OCAtIEF1YnVybmRhbGUgRURTIHZv bCAxICYgMgo+ID4gKyAqICAgLSBDREkgNDAxMzc2IC0gSWJleCBQZWFrIEVEUwo+ID4gKyAqICAg LSByZWYgMjYwMzcsIDI2NjQxIC0gSVBTIEJJT1Mgc3BlYwo+ID4gKyAqICAgLSByZWYgMjY0ODkg LSBOZWhhbGVtIEJJT1Mgd3JpdGVyJ3MgZ3VpZGUKPiA+ICsgKiAgIC0gcmVmIDI2OTIxIC0gSWJl eCBQZWFrIEJJT1MgU3BlY2lmaWNhdGlvbgo+IAo+IGh0dHAgcmVmZXJlbmNlcyB3b3VsZCBiZSBu aWNlLgoKVGhleSB3b3VsZCBiZSwgYnV0IHRoZXNlIGRvY3MgYXJlIG9ubHkgYXZhaWxhYmxlIHVu ZGVyIE5EQS4gIElmIHlvdQpoYXZlIGEgc2FsZXMgb3IgdGVjaG5pY2FsIGNvbnRhY3QgeW91IGNh biB1c2UgdGhlIG51bWJlcnMgaGVyZSB0byBnZXQKdGhlIHJpZ2h0IGRvY3MuCgo+IHJldHVybiAo YXZlcnVuID4gMSk7ID8KPiAKPiBCdXQgdGhpcyBpcyB3cm9uZyB0ZXN0LCBhbnl3YXkuIE9uZSBw cm9jZXNzIHdhaXRpbmcgZm9yIGRpc2ssIGFuZCB5b3UKPiBoYXZlIEQgc3RhdGUgYW5kIGxvYWQg YXZlcmFnZSA+IDEsIHdpdGhvdXQgY3B1IGxvYWQuCgpZZXMsIEknbSBoYXBweSB0byBoYXZlIGEg YmV0dGVyIHRlc3QgaGVyZS4gIE5vdCB0aGF0IGl0IG1hdHRlcnMgKnRvbyoKbXVjaCB0aG91Z2g7 IHdlJ2xsIGFsbG9jYXRlIG1vcmUgcG93ZXIgYnVkZ2V0IHRvIHRoZSBDUFUsIGJ1dCBpdCB3aWxs Cm9ubHkgdXNlIGl0IGlmIG5lZWRlZC4gIEFsbG9jYXRpbmcgaXQgbW9yZSBwb3dlciBqdXN0IGdp dmVzIHRoZSB0dXJibwpib29zdCBjYXBhYmlsaXR5IGFkZGl0aW9uYWwgZnJlcXVlbmN5IGJpbnMu ICBUaGUgQ1BVIHdvbid0IGFjdHVhbGx5IHVzZQp0aG9zZSBiaW5zIHVubGVzcyBpdCBkZXRlY3Rz IHRoYXQgaXQgY2FuIGFuZCB3aWxsIHByb3ZpZGUgc29tZSBiZW5lZml0LgoKPiAKPiA+ICsvKioK PiA+ICsgKiBpcHNfZW5hYmxlX2NwdV90dXJibyAtIGVuYWJsZSB0dXJibyBtb2RlIG9uIGFsbCBD UFVzCj4gPiArICogQGlwczogSVBTIGRyaXZlciBzdHJ1Y3QKPiA+ICsgKgo+ID4gKyAqIEVuYWJs ZSB0dXJibyBtb2RlIGJ5IGNsZWFyaW5nIHRoZSBkaXNhYmxlIGJpdCBpbiBJQTMyX1BFUkZfQ1RM IG9uCj4gPiArICogYWxsIGxvZ2ljYWwgdGhyZWFkcy4KPiA+ICsgKi8KPiA+ICtzdGF0aWMgdm9p ZCBpcHNfZW5hYmxlX2NwdV90dXJibyhzdHJ1Y3QgaXBzX2RyaXZlciAqaXBzKQo+ID4gK3sKPiA+ ICsJLyogQWxyZWFkeSBvbiwgbm8gbmVlZCB0byBtZXNzIHdpdGggTVNScyAqLwo+ID4gKwlpZiAo aXBzLT5fX2NwdV90dXJib19vbikKPiA+ICsJCXJldHVybjsKPiA+ICsKPiA+ICsJb25fZWFjaF9j cHUoZG9fZW5hYmxlX2NwdV90dXJibywgaXBzLCAxKTsKPiA+ICsKPiA+ICsJaXBzLT5fX2NwdV90 dXJib19vbiA9IHRydWU7Cj4gPiArfQo+ID4gKwo+ID4gKy8qKgo+ID4gKyAqIGRvX2Rpc2FibGVf Y3B1X3R1cmJvIC0gaW50ZXJuYWwgdHVyYm8gZGlzYWJsZSBmdW5jdGlvbgo+ID4gKyAqIEBkYXRh OiB1bnVzZWQKPiA+ICsgKgo+ID4gKyAqIEludGVybmFsIGZ1bmN0aW9uIGZvciBhY3R1YWxseSB1 cGRhdGluZyBNU1JzLiAgV2hlbiB3ZSBlbmFibGUvZGlzYWJsZQo+ID4gKyAqIHR1cmJvLCB3ZSBu ZWVkIHRvIGRvIGl0IG9uIGVhY2ggQ1BVOyB0aGlzIGZ1bmN0aW9uIGlzIHRoZSBvbmUgY2FsbGVk Cj4gPiArICogYnkgb25fZWFjaF9jcHUoKSB3aGVuIG5lZWRlZC4KPiA+ICsgKi8KPiA+ICtzdGF0 aWMgdm9pZCBkb19kaXNhYmxlX2NwdV90dXJibyh2b2lkICpkYXRhKQo+ID4gK3sKPiA+ICsJdTY0 IHBlcmZfY3RsOwo+ID4gKwo+ID4gKwlyZG1zcmwoSUEzMl9QRVJGX0NUTCwgcGVyZl9jdGwpOwo+ ID4gKwlpZiAoIShwZXJmX2N0bCAmIElBMzJfUEVSRl9UVVJCT19ESVMpKSB7Cj4gPiArCQlwZXJm X2N0bCB8PSBJQTMyX1BFUkZfVFVSQk9fRElTOwo+ID4gKwkJd3Jtc3JsKElBMzJfUEVSRl9DVEws IHBlcmZfY3RsKTsKPiA+ICsJfQo+ID4gK30KPiA+ICsKPiA+ICsvKioKPiA+ICsgKiBpcHNfZGlz YWJsZV9jcHVfdHVyYm8gLSBkaXNhYmxlIHR1cmJvIG1vZGUgb24gYWxsIENQVXMKPiA+ICsgKiBA aXBzOiBJUFMgZHJpdmVyIHN0cnVjdAo+ID4gKyAqCj4gPiArICogRGlzYWJsZSB0dXJibyBtb2Rl IGJ5IHNldHRpbmcgdGhlIGRpc2FibGUgYml0IGluIElBMzJfUEVSRl9DVEwgb24KPiA+ICsgKiBh bGwgbG9naWNhbCB0aHJlYWRzLgo+ID4gKyAqLwo+ID4gK3N0YXRpYyB2b2lkIGlwc19kaXNhYmxl X2NwdV90dXJibyhzdHJ1Y3QgaXBzX2RyaXZlciAqaXBzKQo+ID4gK3sKPiA+ICsJLyogQWxyZWFk eSBvZmYsIGxlYXZlIGl0ICovCj4gPiArCWlmICghaXBzLT5fX2NwdV90dXJib19vbikKPiA+ICsJ CXJldHVybjsKPiA+ICsKPiA+ICsJb25fZWFjaF9jcHUoZG9fZGlzYWJsZV9jcHVfdHVyYm8sIGlw cywgMSk7Cj4gPiArCj4gPiArCWlwcy0+X19jcHVfdHVyYm9fb24gPSBmYWxzZTsKPiA+ICt9Cj4g Cj4gTWVyZ2UgYWJvdmUgZm91ciBmdW5jdGlvbnMgaW50byB0d28sIGJ5IGhhdmluZyAnZW5hYmxl JyBwYXJhbWV0ZXI/Cj4gCj4gV2hhIHRwcm90ZWN0cyB5b3UgYWdhaW5zdCByYWNlcz8KCkFjY2Vz c2VzIHRvIHRoZXNlIHNob3VsZCBiZSBwcm90ZWN0ZWQgYnkgdGhlIHBhcmFtZXRlciBsb2NrLiAg QW5kIEkKaGF2ZSB0d28gdmFyaWFibGVzIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlbiB0aGUgaGFy ZHdhcmUgYmVpbmcgZW5hYmxlZAp2cy4gdGhlIHNvZnR3YXJlIHJlcXVlc3RpbmcgYW4gZW5hYmxl L2Rpc2FibGUuICBUaGV5IGNvdWxkIHByb2JhYmx5IGJlCm5hbWVkIG1vcmUgY2xlYXJseS4KCj4g PiArLyoqCj4gPiArICogaXBzX2dwdV9idXN5IC0gaXMgR1BVIGJ1c3k/Cj4gPiArICogQGlwczog SVBTIGRyaXZlciBzdHJ1Y3QKPiA+ICsgKgo+ID4gKyAqIENoZWNrIEdQVSBmb3IgbG9hZCB0byBz ZWUgd2hldGhlciB3ZSBzaG91bGQgaW5jcmVhc2UgaXRzIHRoZXJtYWwgYnVkZ2V0Lgo+ID4gKyAq IFdlIG5lZWQgdG8gY2FsbCBpbnRvIHRoZSBpOTE1IGRyaXZlciBpbiB0aGlzIGNhc2UuCj4gPiAr ICoKPiA+ICsgKiBSRVRVUk5TOgo+ID4gKyAqIFRydWUgaWYgdGhlIEdQVSBjb3VsZCB1c2UgbW9y ZSBwb3dlciwgZmFsc2Ugb3RoZXJ3aXNlLgo+ID4gKyAqLwo+ID4gK3N0YXRpYyBib29sIGlwc19n cHVfYnVzeShzdHJ1Y3QgaXBzX2RyaXZlciAqaXBzKQo+ID4gK3sKPiA+ICsJcmV0dXJuIGZhbHNl Owo+ID4gK30KPiAKPiBVaCBvdWNoIDotKS4KClRoaXMgcGFydCBpcyB1c2VsZXNzIHdpdGhvdXQg dGhlIGNvcnJlc3BvbmRpbmcgR1BVIHBvd2VyIHBhdGNoOyB0aGF0J2xsCmFkZCB0aGUgcHJvcGVy IGhvb2tzIGFuZCBjYWxsYmFja3MgaGVyZS4KCj4gPiArLyoqCj4gPiArICogbWNwX2V4Y2VlZGVk IC0gY2hlY2sgd2hldGhlciB3ZSdyZSBvdXRzaWRlIG91ciB0aGVybWFsICYgcG93ZXIgbGltaXRz Cj4gPiArICogQGlwczogSVBTIGRyaXZlciBzdHJ1Y3QKPiA+ICsgKgo+ID4gKyAqIENoZWNrIHdo ZXRoZXIgdGhlIE1DUCBpcyBvdmVyIGl0cyB0aGVybWFsIG9yIHBvd2VyIGJ1ZGdldC4KPiA+ICsg Ki8KPiA+ICtzdGF0aWMgYm9vbCBtY3BfZXhjZWVkZWQoc3RydWN0IGlwc19kcml2ZXIgKmlwcykK PiA+ICt7Cj4gPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gPiArCWJvb2wgcmV0ID0gZmFsc2U7 Cj4gPiArCj4gPiArCXNwaW5fbG9ja19pcnFzYXZlKCZpcHMtPnR1cmJvX3N0YXR1c19sb2NrLCBm bGFncyk7Cj4gPiArCWlmIChpcHMtPm1jcF9hdmdfdGVtcCA+IChpcHMtPm1jcF90ZW1wX2xpbWl0 ICogMTAwKSkKPiA+ICsJCXJldCA9IHRydWU7Cj4gPiArCWlmIChpcHMtPmNwdV9hdmdfcG93ZXIg KyBpcHMtPm1jaF9hdmdfcG93ZXIgPiBpcHMtPm1jcF9wb3dlcl9saW1pdCkKPiA+ICsJCXJldCA9 IHRydWU7Cj4gPiArCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlwcy0+dHVyYm9fc3RhdHVzX2xv Y2ssIGZsYWdzKTsKPiA+ICsKPiA+ICsJcmV0dXJuIHJldDsKPiA+ICt9Cj4gCj4gLi4uYW5kIHBy aW50ayhrZXJuX2NyaXQsIGFzIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbj8pCgpQcm9iYWJseSB3 b3VsZG4ndCBodXJ0OyBidXQgSSd2ZSBnaXZlbiBteXNlbGYgc29tZSBsZWV3YXkgaGVyZTsgaWYK d2UncmUgbmVhciB0aGUgbGltaXQgSSdkIGxpa2UgdGhpcyBjaGVjayB0byByZXR1cm4gdHJ1ZSBh bmQgZm9yY2libHkKdGhyb3R0bGUgdGhpbmdzIGJhY2ssIGp1c3QgdG8gbWFrZSBleHRyYSBzdXJl IHdlIGRvbid0IGdvIG92ZXIgYnVkZ2V0LgpPbiBtb3N0IHN0YW5kYXJkIHZvbHRhZ2UgcGxhdGZv cm1zIHRoaXMgd29uJ3QgcmVhbGx5IG1hdHRlciwgYnV0IG9uCnRpZ2h0bHkgZGVzaWduZWQgdWx0 cmEtbG93IHZvbHRhZ2UgcGxhdGZvcm1zIGl0J3MgaW1wb3J0YW50IHdlIG5ldmVyCmhpdCB0aGUg bGltaXQuCgo+IHByaW50az8KPiAKPiBEb2VzIHRoaXMgaGF2ZSBoYXJkIGxpbWl0IGZvciAyIGNv cmVzPwoKWWVzLCBJIGRvbid0IGJlbGlldmUgd2UnbGwgYmUgZG9pbmcgNCBjb3JlIEFycmFuZGFs ZSBNQ1BzLiAgQW5kCmZvbGxvdy1vbiBjaGlwcyB3b24ndCBuZWVkIHRoaXMgZHJpdmVyLgoKPiAK PiAKPiA+ICsvLwlpZiAoaXBzLT5tY2hfYXZnX3Bvd2VyID4gaXBzLT5tY2hfcG93ZXJfbGltaXQp Cj4gPiArLy8JCXJldCA9IHRydWU7Cj4gCj4gcmVtb3ZlLgo+IAo+ID4gKwlkZXZfZGJnKCZpcHMt PmRldi0+ZGV2LCAic3RhcnRpbmcgaXBzLWFkanVzdCB0aHJlYWRcbiIpOwo+ID4gKwo+ID4gKwkv Kgo+ID4gKwkgKi8KPiA+ICsJZG8gewo+IAo+ID8KCldoYXQgbXkgYmxhbmsgY29tbWVudCB3YXNu J3QgY2xlYXI/IDopCgo+IAo+ID4gK3N0YXRpYyB1MzIgZ2V0X2NwdV9wb3dlcihzdHJ1Y3QgaXBz X2RyaXZlciAqaXBzLCB1MzIgKmxhc3QsIGludCBwZXJpb2QpCj4gPiArewo+ID4gKwl1MzIgdmFs Owo+ID4gKwl1MzIgcmV0Owo+ID4gKwo+ID4gKwkvKgo+ID4gKwkgKiBDRUMgaXMgaW4gam91bGVz LzY1NTM1LiAgVGFrZSBkaWZmZXJlbmNlIG92ZXIgdGltZSB0bwo+ID4gKwkgKiBnZXQgd2F0dHMu Cj4gPiArCSAqLwo+ID4gKwl2YWwgPSB0aG1fcmVhZGwoVEhNX0NFQyk7Cj4gPiArCj4gPiArCS8q IHBlcmlvZCBpcyBpbiBtcyBhbmQgd2Ugd2FudCBtVyAqLwo+ID4gKwlyZXQgPSAoKCh2YWwgLSAq bGFzdCkgKiAxMDAwKSAvIHBlcmlvZCk7Cj4gPiArCXJldCA9IChyZXQgKiAxMDAwKSAvIDY1NTM1 Owo+ID4gKwkqbGFzdCA9IHZhbDsKPiA+ICsKPiA+ICsJcmV0dXJuIHJldDsKPiA+ICt9Cj4gCj4g SSB3b25kZXIgaWYgd2Ugc2hvdWxkIGhhdmUgbWlsbGl3YXR0X3QsIG1zZWNfdCBhbmQgc2ltaWxh ciwgdG8gYWlkCj4gd2l0aCB0eXBlIGNoZWNraW5nLi4uCgpZZWFoLCBrZWVwaW5nIHRyYWNrIG9m IHVuaXRzIGJldHRlciB3b3VsZCBiZSBoYW5keS4KCj4gCj4gPiArc3RhdGljIGludCBzaG93X2Nw dV90ZW1wKHN0cnVjdCBzZXFfZmlsZSAqbSwgdm9pZCAqZGF0YSkKPiA+ICt7Cj4gPiArCXN0cnVj dCBpcHNfZHJpdmVyICppcHMgPSBtLT5wcml2YXRlOwo+ID4gKwo+ID4gKwlzZXFfcHJpbnRmKG0s ICIlZC4lZMOCwrBDXG4iLCBpcHMtPmN0djFfYXZnX3RlbXAgLyAxMDAsCj4gPiArCQkgICBpcHMt PmN0djFfYXZnX3RlbXAgJSAxMDApOwo+ID4gKwo+ID4gKwlyZXR1cm4gMDsKPiA+ICt9Cj4gPiAr Cj4gCj4gUGxlYXNlIG5vIHVuaWNvZGUgYXQgbGVhc3QgaW4gdXNlciBpbnRlcmZhY2VzLiBPdWNo IGFuZCBpdCBpcyBzdWJ0bHkKPiB3cm9uZy4gWW91IHJlYWxseSB3YW50ICIlZC4lMDJkIi4KPiAK PiBPaywgaW50ZXJlc3RpbmcuIFdoYXQga2luZCBvZiBzcGVlZHVwIGNhbiBpdCBicmluZz8KCkZv ciB0aGUgQ1BVIHRoZSBwZXJmIHVwc2lkZSBpc24ndCB0aGF0IGdyZWF0LCBtYXliZSA1JSBvciBz bywgYW5kIG9ubHkKd2l0aCB2ZXJ5IHNwZWNpZmljIHdvcmtsb2FkcyB0aGF0IHRha2UgYWR2YW50 YWdlIG9mIHR1cmJvIGJvb3N0LiAgRm9yCmdyYXBoaWNzIHRoZSB1cHNpZGUgaXMgc2lnbmlmaWNh bnQsIGF0IGxlYXN0IDE1JSBpbiBteSBiYXNpYyB0ZXN0cyBzbwpmYXIsIGJ1dCBFcmljIGFuZCBL ZWl0aCBoYXZlIG1lYXN1cmVkIDN4IGdhaW5zIGluIHNvbWUgY2FzZXMuCgotLSAKSmVzc2UgQmFy bmVzLCBJbnRlbCBPcGVuIFNvdXJjZSBUZWNobm9sb2d5IENlbnRlcgpfX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpJbnRlbC1nZnggbWFpbGluZyBsaXN0Cklu dGVsLWdmeEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cDovL2xpc3RzLmZyZWVkZXNrdG9wLm9y Zy9tYWlsbWFuL2xpc3RpbmZvL2ludGVsLWdmeAo=