From: Maynard J. <may...@us...> - 2007-01-29 19:45:39
|
On December 14, 2006, I posted a patch that added support to the OProfile kernel driver for profiling Cell SPUs. There have been some changes/fixes to this patch since the original posting (including forward porting from 2.6.18-based kernel to 2.6.20-rc1), so I am reposting the patch for review now. This patch relies upon the following patches that have not been accepted yet: 1. oprofile cleanup patch (submitted on Nov 27) 2. Fix for PPU profiling (not submitted yet, since it depends on #1) 3. SPU task notification patch (last submitted on Jan 26) For those who may want to apply and build the oprofile SPU support patch, it would be necessary to first apply the above patches. For convenience, I will post all three of the above patches, along with the oprofile SPU support patch. Comments appreciated. Thank you. Maynard Johnson IBM LTC Toolchain |
From: Maynard J. <may...@us...> - 2007-01-29 19:47:00
Attachments:
oprof-ppu-cleanup1.diff
|
From: Arnd B. <ar...@ar...> - 2007-01-30 04:08:20
|
On Monday 29 January 2007 20:46, Maynard Johnson wrote: > This is a clean up patch that includes the following changes: >=20 > =A0 =A0 =A0 =A0 -It removes some macro definitions that are only used once > =A0 =A0 =A0 =A0 =A0with the actual code. > =A0 =A0 =A0 =A0 -Some comments were added to clarify the code based on fe= edback > =A0 =A0 =A0 =A0 =A0from the community. > =A0 =A0 =A0 =A0 -The write_pm_cntrl() and set_count_mode() were passed a = structure > =A0 =A0 =A0 =A0 =A0element from a global variable. =A0The argument was re= moved so the > =A0 =A0 =A0 =A0 =A0functions now just operate on the global directly. > =A0 =A0 =A0 =A0 -The set_pm_event() function call in the cell_virtual_cnt= r() routine > =A0 =A0 =A0 =A0 =A0was moved to a for-loop before the for_each_cpu loop >=20 > Signed-off-by: Carl Love <ca...@us...> > Signed-off-by: Maynard Johnson <mp...@us...> >=20 Acked-by: Arnd Bergmann <arn...@de...> Just a small side note: Please give each of your patches a one-line summary in the subject of the email. I'm filing this one under: "cell: oprofile cleanup". It would also be good if you could use a mailer that sends out patches as inline, so you don't need to resort to using attachments. Arnd <>< |
From: Christoph H. <hc...@ls...> - 2007-01-30 10:39:31
|
On Mon, Jan 29, 2007 at 01:46:50PM -0600, Maynard Johnson wrote: > > I don't think the macro removal is helpful, getting rid of the names makes the code less readable to me. |
From: Carl L. <ce...@us...> - 2007-01-30 22:50:33
|
Christoph: In our earlier work on the PPU profiling patch, Benjamin Herrenschmidt said that we should remove macros that are only used once and just put the actual code in. That is why the macros were removed. Carl Love On Tue, 2007-01-30 at 11:39 +0100, Christoph Hellwig wrote: > On Mon, Jan 29, 2007 at 01:46:50PM -0600, Maynard Johnson wrote: > > > > > > I don't think the macro removal is helpful, getting rid of the names > makes the code less readable to me. > _______________________________________________ > cbe-oss-dev mailing list > cbe...@oz... > https://ozlabs.org/mailman/listinfo/cbe-oss-dev |
From: Benjamin H. <be...@ke...> - 2007-01-30 23:00:08
|
On Tue, 2007-01-30 at 14:49 -0800, Carl Love wrote: > Christoph: > > In our earlier work on the PPU profiling patch, Benjamin Herrenschmidt > said that we should remove macros that are only used once and just put > the actual code in. That is why the macros were removed. I've looked at the macros you remove and indeed, they look like stuff you actually want to keep in macros. I don't have off the top of my head the circumstances where I asked you to remove macros in the PPE code, but I'm sure it was different. Ben. |
From: Benjamin H. <be...@ke...> - 2007-01-30 22:57:33
|
On Tue, 2007-01-30 at 14:49 -0800, Carl Love wrote: > Christoph: > > In our earlier work on the PPU profiling patch, Benjamin Herrenschmidt > said that we should remove macros that are only used once and just put > the actual code in. That is why the macros were removed. Heh... there is a balance to be found... In some cases, inline functions might be better too. Ben. |
From: Christoph H. <hc...@ls...> - 2007-01-31 08:47:29
|
On Wed, Jan 31, 2007 at 09:57:26AM +1100, Benjamin Herrenschmidt wrote: > On Tue, 2007-01-30 at 14:49 -0800, Carl Love wrote: > > Christoph: > > > > In our earlier work on the PPU profiling patch, Benjamin Herrenschmidt > > said that we should remove macros that are only used once and just put > > the actual code in. That is why the macros were removed. > > Heh... there is a balance to be found... In some cases, inline functions > might be better too. Well, unless there's a very good reasons against it (token pasting, header pollution) inlines are always preferable over macros, but I didn't want to bring that issue up aswell.. |
From: Maynard J. <may...@us...> - 2007-01-29 19:48:02
Attachments:
oprof-ppu-fix2.diff
|
From: Arnd B. <ar...@ar...> - 2007-01-30 04:09:09
|
On Monday 29 January 2007 20:47, Maynard Johnson wrote: > The code was setting up the debug bus for group 21 when profiling on th= e=20 > event PPU CYCLES. =A0The debug bus is not actually used by the hardware=20 > performance counters when counting PPU CYCLES. =A0Setting up the debug bus > for PPU CYCLES causes signal routing conflicts on the debug bus when=20 > profiling PPU cycles and another PPU event. =A0This patch fixes the code = to=20 > only setup the debug bus to route the performance signals for the non > PPU CYCLE events. >=20 > Signed-off-by: Maynard Johnson <mp...@us...> > Signed-off-by: Carl Love <ca...@us...> Acked-by: Arnd Bergmann <arn...@de...> Any suggestion for a one-line patch title? |
From: Carl L. <ce...@us...> - 2007-01-30 23:51:15
|
Arnd: Well most of the patch is simply cleaning up the pm_rtas_activate_signals() routine. I would be think "pm_rtas_activat_signals routine cleanup" would be good. Carl Love On Tue, 2007-01-30 at 05:08 +0100, Arnd Bergmann wrote: > On Monday 29 January 2007 20:47, Maynard Johnson wrote: > > The code was setting up the debug bus for group 21 when profiling on the > > event PPU CYCLES. The debug bus is not actually used by the hardware > > performance counters when counting PPU CYCLES. Setting up the debug bus > > for PPU CYCLES causes signal routing conflicts on the debug bus when > > profiling PPU cycles and another PPU event. This patch fixes the code to > > only setup the debug bus to route the performance signals for the non > > PPU CYCLE events. > > > > Signed-off-by: Maynard Johnson <mp...@us...> > > Signed-off-by: Carl Love <ca...@us...> > > Acked-by: Arnd Bergmann <arn...@de...> > > Any suggestion for a one-line patch title? > _______________________________________________ > cbe-oss-dev mailing list > cbe...@oz... > https://ozlabs.org/mailman/listinfo/cbe-oss-dev |
From: Maynard J. <may...@us...> - 2007-01-29 19:48:26
Attachments:
spu-notifier.patch
|
From: Maynard J. <may...@us...> - 2007-01-29 19:49:20
Attachments:
oprof-spu.diff
|
From: Benjamin H. <be...@ke...> - 2007-01-30 07:53:58
|
> > +/* Defines used for sync_start */ > > +#define SKIP_GENERIC_SYNC 0 > > +#define SYNC_START_ERROR -1 > > +#define DO_GENERIC_SYNC 1 > > + > > +typedef struct vma_map > > +{ > > + struct vma_map *next; > > + unsigned int vma; > > + unsigned int size; > > + unsigned int offset; > > + unsigned int guard_ptr; > > + unsigned int guard_val; > > +} vma_map_t; I haven't had time to look in details yet but in that context, what does "vma" stands for ? There's already an important vm data structure in linux routinely called "vma" and thus I suspect this is a poor naming choice as it will cause confusion. Cheers, Ben. |
From: Christoph H. <hc...@ls...> - 2007-01-30 10:41:28
|
On Tue, Jan 30, 2007 at 06:53:50PM +1100, Benjamin Herrenschmidt wrote: > > > > +/* Defines used for sync_start */ > > > +#define SKIP_GENERIC_SYNC 0 > > > +#define SYNC_START_ERROR -1 > > > +#define DO_GENERIC_SYNC 1 > > > + > > > +typedef struct vma_map > > > +{ > > > + struct vma_map *next; > > > + unsigned int vma; > > > + unsigned int size; > > > + unsigned int offset; > > > + unsigned int guard_ptr; > > > + unsigned int guard_val; > > > +} vma_map_t; > > I haven't had time to look in details yet but in that context, what does > "vma" stands for ? There's already an important vm data structure in > linux routinely called "vma" and thus I suspect this is a poor naming > choice as it will cause confusion. It looks like it actually is dealing with vma to me. But then again: - please don't use typedefs for structures - there might be a more descriptive name for this than just vma_map |
From: Maynard J. <may...@us...> - 2007-01-30 23:09:21
|
Christoph Hellwig wrote: > On Tue, Jan 30, 2007 at 06:53:50PM +1100, Benjamin Herrenschmidt wrote: > >>>>+/* Defines used for sync_start */ >>>>+#define SKIP_GENERIC_SYNC 0 >>>>+#define SYNC_START_ERROR -1 >>>>+#define DO_GENERIC_SYNC 1 >>>>+ >>>>+typedef struct vma_map >>>>+{ >>>>+ struct vma_map *next; >>>>+ unsigned int vma; >>>>+ unsigned int size; >>>>+ unsigned int offset; >>>>+ unsigned int guard_ptr; >>>>+ unsigned int guard_val; >>>>+} vma_map_t; >> >>I haven't had time to look in details yet but in that context, what does >>"vma" stands for ? There's already an important vm data structure in >>linux routinely called "vma" and thus I suspect this is a poor naming >>choice as it will cause confusion. > > > It looks like it actually is dealing with vma to me. But then again: > > - please don't use typedefs for structures > - there might be a more descriptive name for this than just vma_map Yes, I'll come up with some (hopefully) better name. > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys - and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > oprofile-list mailing list > opr...@li... > https://lists.sourceforge.net/lists/listinfo/oprofile-list |
From: Benjamin H. <be...@ke...> - 2007-01-30 23:34:12
|
> I've given this some more thought, and I'm coming to the conclusion that > a pure array-based implementation for holding cached_info (getting rid > of the lists) would work well for the vast majority of cases in which > OProfile will be used. Yes, it is true that the mapping of an SPU > context to a phsyical spu-numbered array location cannot be guaranteed > to stay valid, and that's why I discard the cached_info at that array > location when the SPU task is switched out. Yes, it would be terribly > inefficient if the same SPU task gets switched back in later and we > would have to recreate the cached_info. However, I contend that > OProfile users are interested in profiling one application at a time. > They are not going to want to muddy the waters with multiple SPU apps > running at the same time. I can't think of any reason why someone would > conscisouly choose to do that. > > Any thoughts from the general community, especially OProfile users? Well, it's my understanding that quite a few typical usage scenario involve different tasks running on different SPUs passing each other data around. Ben. |
From: Maynard J. <may...@us...> - 2007-01-31 00:29:53
|
Benjamin Herrenschmidt wrote: >>I've given this some more thought, and I'm coming to the conclusion that >>a pure array-based implementation for holding cached_info (getting rid >>of the lists) would work well for the vast majority of cases in which >>OProfile will be used. Yes, it is true that the mapping of an SPU >>context to a phsyical spu-numbered array location cannot be guaranteed >>to stay valid, and that's why I discard the cached_info at that array >>location when the SPU task is switched out. Yes, it would be terribly >>inefficient if the same SPU task gets switched back in later and we >>would have to recreate the cached_info. However, I contend that >>OProfile users are interested in profiling one application at a time. >>They are not going to want to muddy the waters with multiple SPU apps >>running at the same time. I can't think of any reason why someone would >>conscisouly choose to do that. >> >>Any thoughts from the general community, especially OProfile users? > > > Well, it's my understanding that quite a few typical usage scenario > involve different tasks running on different SPUs passing each other > data around. That shouldn't be a problem. I would consider this to be "one large application" consisting of multiple SPU binaries running simultaneously. Such a scenario can be handled with no negative performance impact using a simple 16 element array of cached_info objects -- as long as there isn't (much) SPU task switching being done. -Maynard > > Ben. > > |
From: Arnd B. <ar...@ar...> - 2007-01-30 04:24:51
|
On Monday 29 January 2007 20:48, Maynard Johnson wrote: > Subject: Enable SPU switch notification to detect currently active SPU tasks. > > From: Maynard Johnson <may...@us...> > > This patch adds to the capability of spu_switch_event_register so that the > caller is also notified of currently active SPU tasks. It also exports > spu_switch_event_register and spu_switch_event_unregister. > > Signed-off-by: Maynard Johnson <mp...@us...> I looked through it again, and think I found a serious bug, but that should be easy enough to solve: > +static void notify_spus_active(void) > +{ > + int node; > + /* Wake up the active spu_contexts. When the awakened processes > + * sees their notify_active flag is set, they will call > + * spu_switch_notify(); > + */ > + for (node = 0; node < MAX_NUMNODES; node++) { > + struct spu *spu; > + mutex_lock(&spu_prio->active_mutex[node]); > + list_for_each_entry(spu, &spu_prio->active_list[node], list) { > + struct spu_context *ctx = spu->ctx; [side note] There is a small whitespace breakage in here, please make sure you always use tabs for indenting, not space characters. [/side note] > @@ -45,9 +45,10 @@ > u64 pte_fault; > > *stat = ctx->ops->status_read(ctx); > - if (ctx->state != SPU_STATE_RUNNABLE) > - return 1; > + > spu = ctx->spu; > + if (ctx->state != SPU_STATE_RUNNABLE || spu->notify_active) > + return 1; > pte_fault = spu->dsisr & > (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED); > return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0; > @@ -305,6 +306,7 @@ > u32 *npc, u32 *event) > { > int ret; > + struct spu * spu; > u32 status; > > if (down_interruptible(&ctx->run_sema)) > @@ -318,8 +320,16 @@ > > do { > ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, &status)); > + spu = ctx->spu; > if (unlikely(ret)) > break; > + if (unlikely(spu->notify_active)) { > + spu->notify_active = 0; > + if (!(status & SPU_STATUS_STOPPED_BY_STOP)) { > + spu_switch_notify(spu, ctx); > + continue; > + } > + } This is before spu_reacquire_runnable, so in case the spu got preempted at the same time when oprofile was enabled, ctx->spu is NULL, and you can't load the notify_active flag from it. On solution would be to move the notify_active flag from ctx->spu into ctx itself, but maybe there are other ways to solve this. Thanks, Arnd <>< |
From: Maynard J. <may...@us...> - 2007-01-30 15:33:11
|
Arnd Bergmann wrote: > On Monday 29 January 2007 20:48, Maynard Johnson wrote: > >>Subject: Enable SPU switch notification to detect currently active SPU tasks. >> >>From: Maynard Johnson <may...@us...> >> >>This patch adds to the capability of spu_switch_event_register so that the >>caller is also notified of currently active SPU tasks. It also exports >>spu_switch_event_register and spu_switch_event_unregister. >> >>Signed-off-by: Maynard Johnson <mp...@us...> > > > I looked through it again, and think I found a serious bug, but that > should be easy enough to solve: > > >>+static void notify_spus_active(void) >>+{ >>+ int node; >>+ /* Wake up the active spu_contexts. When the awakened processes >>+ * sees their notify_active flag is set, they will call >>+ * spu_switch_notify(); >>+ */ >>+ for (node = 0; node < MAX_NUMNODES; node++) { >>+ struct spu *spu; >>+ mutex_lock(&spu_prio->active_mutex[node]); >>+ list_for_each_entry(spu, &spu_prio->active_list[node], list) { >>+ struct spu_context *ctx = spu->ctx; > > > [side note] > There is a small whitespace breakage in here, please make sure you always > use tabs for indenting, not space characters. > [/side note] > > >>@@ -45,9 +45,10 @@ >> u64 pte_fault; >> >> *stat = ctx->ops->status_read(ctx); >>- if (ctx->state != SPU_STATE_RUNNABLE) >>- return 1; >>+ >> spu = ctx->spu; >>+ if (ctx->state != SPU_STATE_RUNNABLE || spu->notify_active) >>+ return 1; >> pte_fault = spu->dsisr & >> (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED); >> return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0; >>@@ -305,6 +306,7 @@ >> u32 *npc, u32 *event) >> { >> int ret; >>+ struct spu * spu; >> u32 status; >> >> if (down_interruptible(&ctx->run_sema)) >>@@ -318,8 +320,16 @@ >> >> do { >> ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, &status)); >>+ spu = ctx->spu; >> if (unlikely(ret)) >> break; >>+ if (unlikely(spu->notify_active)) { >>+ spu->notify_active = 0; >>+ if (!(status & SPU_STATUS_STOPPED_BY_STOP)) { >>+ spu_switch_notify(spu, ctx); >>+ continue; >>+ } >>+ } > > > This is before spu_reacquire_runnable, so in case the spu got > preempted at the same time when oprofile was enabled, ctx->spu > is NULL, and you can't load the notify_active flag from it. > > On solution would be to move the notify_active flag from ctx->spu > into ctx itself, but maybe there are other ways to solve this. In an earlier review of this patch, Christopher Hellwig suggested I move the notify_active flag to be a bit in the sched_flags field that's added in his scheduler patch series. If this patch series will be a available in an "Arnd" tree that we'll be using for our current OProfile development, perhaps I should wait until that time to change this, since the window of vulnerability is quite small. What do you think? -Maynard > > Thanks, > > Arnd <>< |
From: Arnd B. <ar...@ar...> - 2007-01-31 00:37:08
|
On Tuesday 30 January 2007 16:31, Maynard Johnson wrote: >=20 > > On solution would be to move the notify_active flag from ctx->spu > > into ctx itself, but maybe there are other ways to solve this. > In an earlier review of this patch, Christopher Hellwig suggested I move= =20 > the notify_active flag to be a bit in the sched_flags field that's added= =20 > in his scheduler patch series. =A0If this patch series will be a availabl= e=20 > in an "Arnd" tree that we'll be using for our current OProfile=20 > development, perhaps I should wait until that time to change this, since= =20 > the window of vulnerability is quite small. =A0What do you think? Sounds good to me. Arnd <>< |
From: Arnd B. <ar...@ar...> - 2007-01-30 07:39:20
|
T24gTW9uZGF5IDI5IEphbnVhcnkgMjAwNyAyMDo0OCwgTWF5bmFyZCBKb2huc29uIHdyb3RlOgo+ IFN1YmplY3Q6IEFkZCBzdXBwb3J0IHRvIE9Qcm9maWxlIGZvciBwcm9maWxpbmcgQ2VsbCBCRSBT UFVzCj4gCj4gRnJvbTogTWF5bmFyZCBKb2huc29uIDxtYXluYXJkakB1cy5pYm0uY29tPgo+IAo+ IFRoaXMgcGF0Y2ggdXBkYXRlcyB0aGUgZXhpc3RpbmcgYXJjaC9wb3dlcnBjL29wcm9maWxlL29w X21vZGVsX2NlbGwuYwo+IHRvIGFkZCBpbiB0aGUgU1BVIHByb2ZpbGluZyBjYXBhYmlsaXRpZXMu IKBJbiBhZGRpdGlvbiwgYSAnY2VsbCcgc3ViZGlyZWN0b3J5Cj4gd2FzIGFkZGVkIHRvIGFyY2gv cG93ZXJwYy9vcHJvZmlsZSB0byBob2xkIENlbGwtc3BlY2lmaWMgU1BVIHByb2ZpbGluZwo+IGNv ZGUuCj4gCj4gU2lnbmVkLW9mZi1ieTogQ2FybCBMb3ZlIDxjYXJsbEB1cy5pYm0uY29tPgo+IFNp Z25lZC1vZmYtYnk6IE1heW5hcmQgSm9obnNvbiA8bXBqb2huQHVzLmlibS5jb20+CgpJIGNhbid0 IHJlYWxseSBzYXkgbXVjaCBhYm91dCB0aGUgY29tbW9uIG9wcm9maWxlIGZpbGVzIHRoYXQgeW91 IGFyZQp0b3VjaGluZywgbWF5YmUgc29tZW9uZSBmcm9tIG9wcm9maWxlLWxpc3QgKFBoaWxpcHBl PykgdG8gbG9vayBvdmVyIHRoZW0KYW5kIGFjay9uYWNrIHRoZW0uCgo+ICsjZGVmaW5lIG51bWJl cl9vZl9vbmxpbmVfbm9kZXMobm9kZXMpIHsgoCCgIKAgoFwKPiArIKAgoCCgIKB1MzIgY3B1OyB1 MzIgdG1wOyCgIKAgoCCgIKAgoCCgIKAgoCCgIKBcCj4gKyCgIKAgoCCgbm9kZXMgPSAwOyCgIKAg oCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgXAo+ICsgoCCgIKAgoGZvcl9lYWNoX29ubGluZV9jcHUo Y3B1KSB7IKAgoCCgIKAgoCCgIFwKPiArIKAgoCCgIKAgoCCgIKAgoHRtcCA9IGNiZV9jcHVfdG9f bm9kZShjcHUpICsgMTtcCj4gKyCgIKAgoCCgIKAgoCCgIKBpZiAodG1wID4gbm9kZXMpIKAgoCCg IKAgoCCgIKAgXAo+ICsgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKBub2RlcysrOyCgIKAgoCCgIKAg oCCgIFwKPiAroKCgoKCgoH0goCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoFwK PiArfQoKSSd2ZSBiZWVuIGRpc2N1c3Npbmcgd2l0aCBiZW5oIGFib3V0IGEgYmV0dGVyIHdheSB0 byBkbyB0aGlzLiBXZSBzaG91bGQKY2hhbmdlIGFsbCB0aGUgcmVmZXJlbmNlcyB0byBub2RlcyBh bmQgY3B1IG51bWJlcnMgdG8gc29tZXRoaW5nIG1vcmUKY29ycmVjdCBpbiB0aGUgZnV0dXJlLCBz byB3ZSBnZXQgcmlkIG9mIHRoZSBhc3N1bXB0aW9uIHRoYXQgZWFjaApudW1hIG5vZGUgaXMgYSBj ZWxsIGNoaXAuIEl0J3MgcHJvYmFibHkgYmVzdCB0byBsZWF2ZSB5b3VyIGNvZGUgYXMKaXMgZm9y IG5vdywgYnV0IHdlIG5lZWQgdG8gcmVtZW1iZXIgdGhpcyBvbmUgd2hlbiBjbGVhbmluZyBpdCB1 cC4KCllvdSBzaG91bGQgaG93ZXZlciBjb252ZXJ0IHRoaXMgaW50byBhbiBpbmxpbmUgZnVuY3Rp b24Kb2YgcHJvdG90eXBlIAoKc3RhdGljIGlubGluZSBpbnQgbnVtYmVyX29mX29ubGluZV9ub2Rl cyh2b2lkKQoKaW5zdGVhZCBvZiBhIG1hY3JvLgoKPiArLyogRGVmaW5lcyB1c2VkIGZvciBzeW5j X3N0YXJ0ICovCj4gKyNkZWZpbmUgU0tJUF9HRU5FUklDX1NZTkMgMAo+ICsjZGVmaW5lIFNZTkNf U1RBUlRfRVJST1IgLTEKPiArI2RlZmluZSBET19HRU5FUklDX1NZTkMgMQo+ICsKPiArdHlwZWRl ZiBzdHJ1Y3Qgdm1hX21hcAo+ICt7Cj4gK6CgoKCgoKBzdHJ1Y3Qgdm1hX21hcCAqbmV4dDsKPiAr oKCgoKCgoHVuc2lnbmVkIGludCB2bWE7Cj4gK6CgoKCgoKB1bnNpZ25lZCBpbnQgc2l6ZTsKPiAr oKCgoKCgoHVuc2lnbmVkIGludCBvZmZzZXQ7Cj4gK6CgoKCgoKB1bnNpZ25lZCBpbnQgZ3VhcmRf cHRyOwo+ICugoKCgoKCgdW5zaWduZWQgaW50IGd1YXJkX3ZhbDsKPiArfSB2bWFfbWFwX3Q7Cgpw bGVhc2UgZG9uJ3QgdHlwZWRlZiBzdHJ1Y3R1cmVzLgoKPiArLyogVGhlIHRocmVlIGZ1bmN0aW9u cyBiZWxvdyBhcmUgZm9yIG1haW50YWluaW5nIGFuZCBhY2Nlc3NpbmcKPiArICogdGhlIHZtYS10 by1maWxlIG9mZnNldCBtYXAuCj4gKyAqLwo+ICt2bWFfbWFwX3QgKiBjcmVhdGVfdm1hX21hcChj b25zdCBzdHJ1Y3Qgc3B1ICogc3B1LCB1NjQgb2JqZWN0aWQpOwo+ICt1bnNpZ25lZCBpbnQgdm1h X21hcF9sb29rdXAodm1hX21hcF90ICptYXAsIHVuc2lnbmVkIGludCB2bWEsCj4gK6CgoKCgoKCg oKCgoKCgoKCgoKCgoKCgIKAgoGNvbnN0IHN0cnVjdCBzcHUgKiBhU3B1KTsKPiArdm9pZCB2bWFf bWFwX2ZyZWUoc3RydWN0IHZtYV9tYXAgKm1hcCk7Cj4gKwo+ICsvKgo+ICsgKiBFbnRyeSBwb2lu dCBmb3IgU1BVIHByb2ZpbGluZy4KPiArICogY3ljbGVzX3Jlc2V0IGlzIHRoZSBTUFVfQ1lDTEVT IGNvdW50IHZhbHVlIHNwZWNpZmllZCBieSB0aGUgdXNlci4KPiArICovCj4gK3ZvaWQgc3RhcnRf c3B1X3Byb2ZpbGluZyh1bnNpZ25lZCBpbnQgY3ljbGVzX3Jlc2V0KTsKPiArCj4gK3ZvaWQgc3Rv cF9zcHVfcHJvZmlsaW5nKHZvaWQpOwo+ICsKPiArIAo+ICsvKiBhZGQgdGhlIG5lY2Vzc2FyeSBw cm9maWxpbmcgaG9va3MgKi8KPiAraW50IHNwdV9zeW5jX3N0YXJ0KHZvaWQpOwo+ICsKPiArLyog cmVtb3ZlIHRoZSBob29rcyAqLwo+ICtpbnQgc3B1X3N5bmNfc3RvcCh2b2lkKTsKPiArIAo+ICsv KiBSZWNvcmQgU1BVIHByb2dyYW0gY291bnRlciBzYW1wbGVzIHRvIHRoZSBvcHJvZmlsZSBldmVu dCBidWZmZXIuICovCj4gK3ZvaWQgc3B1X3N5bmNfYnVmZmVyKGludCBzcHVfbnVtLCB1bnNpZ25l ZCBpbnQgKiBzYW1wbGVzLCAKPiAroKCgoKCgoKCgoKCgoKCgIKAgoCBpbnQgbnVtX3NhbXBsZXMp Owo+ICsKPiArI2VuZGlmIKAgoC8vIFBSX1VUSUxfSCAKPiBJbmRleDogbGludXgtMi42LjIwLXJj MS9hcmNoL3Bvd2VycGMvb3Byb2ZpbGUvY2VsbC9zcHVfcHJvZmlsZXIuYwo+ID09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0K PiAtLS0gL2Rldi9udWxsoKCgMTk3MC0wMS0wMSAwMDowMDowMC4wMDAwMDAwMDAgKzAwMDAKPiAr KysgbGludXgtMi42LjIwLXJjMS9hcmNoL3Bvd2VycGMvb3Byb2ZpbGUvY2VsbC9zcHVfcHJvZmls ZXIuY6CgMjAwNy0wMS0yOSAxMDozMjowMy4zOTI3ODg2OTYgLTA2MDAKPiBAQCAtMCwwICsxLDIw NCBAQAo+ICsvKgo+ICsgKiBDZWxsIEJyb2FkYmFuZCBFbmdpbmUgT1Byb2ZpbGUgU3VwcG9ydAo+ ICsgKgo+ICsgKiAoQykgQ29weXJpZ2h0IElCTSBDb3Jwb3JhdGlvbiAyMDA2Cj4gKyAqCj4gKyAq IEF1dGhvcnM6IE1heW5hcmQgSm9obnNvbiA8bWF5bmFyZGpAdXMuaWJtLmNvbT4KPiArICogoCCg IKAgoCCgQ2FybCBMb3ZlIDxjYXJsbEB1cy5pYm0uY29tPgo+ICsgKgo+ICsgKiBUaGlzIHByb2dy YW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCj4gKyAq IG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNl bnNlCj4gKyAqIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBl aXRoZXIgdmVyc2lvbgo+ICsgKiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24p IGFueSBsYXRlciB2ZXJzaW9uLgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxsaW51eC9ocnRpbWVy Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbXAuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4K PiArI2luY2x1ZGUgPGFzbS9jZWxsLXBtdS5oPgo+ICsjaW5jbHVkZSAicHJfdXRpbC5oIgo+ICsK PiArI2RlZmluZSBUUkFDRV9BUlJBWV9TSVpFIDEwMjQKPiArc3RhdGljIHUzMiAqIHNhbXBsZXM7 Cj4gK3N0YXRpYyB1MzIgKiBzYW1wbGVzX3Blcl9ub2RlOwo+ICsKPiArc3RhdGljIGludCBzcHVf cHJvZl9ydW5uaW5nID0gMDsKPiArc3RhdGljIHVuc2lnbmVkIGludCBwcm9maWxpbmdfaW50ZXJ2 YWwgPSAwOwo+ICsKPiArZXh0ZXJuIGludCBudW1fbm9kZXM7Cj4gK2V4dGVybiB1bnNpZ25lZCBp bnQga2h6ZnJlcTsKCllvdSByZWFsbHkgY2FuJ3QgaGF2ZSBnbG9iYWwgdmFyaWFibGUgd2l0aCBz dWNoIGdlbmVyaWMgbmFtZXMuIEZvcgpzdGF0aWMgdmFyaWFibGVzLCBpdCdzIGxlc3Mgb2YgYSBw cm9ibGVtLCBzaW5jZSB0aGV5IGFyZSBub3QgaW4gdGhlCnNhbWUgbmFtZSBzcGFjZSwgYnV0IGZv ciBlYXNpZXIgZGVidWdnaW5nLCBpdCdzIGdvb2QgdG8gYWx3YXlzIGhhdmUKdGhlIG5hbWUgb2Yg eW91ciBtb2R1bGUgKGUuZy4gc3B1X3Byb2ZfKSBhcyBhIHByZWZpeCB0byB0aGUgaWRlbnRpZmll ci4KCk9mIGNvdXJzZSwgdGhlIGJlc3Qgd2F5IHdvdWxkIGJlIHRvIGF2b2lkIGdsb2JhbCBhbmQg c3RhdGljIHZhcmlhYmxlcwplbnRpcmVseSwgYnV0IHRoYXQncyBub3QgYWx3YXlzIHBvc3NpYmxl LgoKPiArLyoKPiArICogT3Byb2ZpbGUgc2V0dXAgZnVuY3Rpb25zCj4gKyAqLwo+ICsKPiArI2Rl ZmluZSBOVU1fU1BVX0JJVFNfVFJCVUYgMTYKPiArI2RlZmluZSBTUFVTX1BFUl9UQl9FTlRSWSCg IDQKPiArI2RlZmluZSBTUFVTX1BFUl9OT0RFIKAgoCCgIDgKPiArCj4gKy8qIAo+ICsgKiBDb2xs ZWN0IHRoZSBTUFUgcHJvZ3JhbSBjb3VudGVyIHNhbXBsZXMgZnJvbSB0aGUgdHJhY2UgYnVmZmVy Lgo+ICsgKiBUaGUgZ2xvYmFsIHZhcmlhYmxlIHVzYWdlIGlzIGFzIGZvbGxvd3M6Cj4gKyAqIKAg oHNhbXBsZXNbPHRvdGFsLXNwdXM+XVtUUkFDRV9BUlJBWV9TSVpFXSAtIGFycmF5IHRvIHN0b3Jl IFNQVSBQQyBzYW1wbGVzCj4gKyAqIKAgoCCgIKAgoCBBc3N1bXB0aW9uLCB0aGUgYXJyYXkgd2ls bCBiZSBhbGwgemVyb3Mgb24gZW50cnkuCj4gKyAqIKAgoHUzMiBzYW1wbGVzX3Blcl9ub2RlW251 bV9ub2Rlc10gLSBhcnJheSBvZiBob3cgbWFueSB2YWxpZCBzYW1wbGVzIHBlciBub2RlCj4gKyAq Lwo+ICtzdGF0aWMgdm9pZCBjZWxsX3NwdV9wY19jb2xsZWN0aW9uKHZvaWQpCj4gK3sKPiAroKCg oKCgoGludCBjcHU7Cj4gK6CgoKCgoKBpbnQgbm9kZTsKPiAroKCgoKCgoGludCBzcHU7Cj4gK6Cg oKCgoKB1MzIgdHJhY2VfYWRkcjsKPiArIKAgoCCgIKAvKiB0aGUgdHJhY2UgYnVmZmVyIGlzIDEy OCBiaXRzICovCj4gK6CgoKCgoKB1NjQgdHJhY2VfYnVmZmVyWzJdOwo+ICugoKCgoKCgdTY0IHNw dV9wY19sb3dlcjsgoAo+ICugoKCgoKCgdTY0IHNwdV9wY191cHBlcjsKPiAroKCgoKCgoHU2NCBz cHVfbWFzazsKPiAroKCgoKCgoGludCBlbnRyeSwgbm9kZV9mYWN0b3I7Cj4gK6CgoKCgoKAvLyBw cm9jZXNzIHRoZSBjb2xsZWN0ZWQgU1BVIFBDIGZvciBlYWNoIG5vZGUKPiAroKCgoKCgoGZvcl9l YWNoX29ubGluZV9jcHUoY3B1KSB7Cj4gK6CgoKCgoKCgoKCgoKCgoGlmIChjYmVfZ2V0X2h3X3Ro cmVhZF9pZChjcHUpKQo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoGNvbnRpbnVlOwo+ICsKPiAr oKCgoKCgoKCgoKCgoKCgbm9kZSA9IGNiZV9jcHVfdG9fbm9kZShjcHUpOwo+ICugoKCgoKCgoKCg oKCgoKBub2RlX2ZhY3RvciA9IG5vZGUgKiBTUFVTX1BFUl9OT0RFOwo+ICsgoCCgIKAgoCCgIKAg oCCgLyogbnVtYmVyIG9mIHZhbGlkIGVudHJpZXMgZm9yIHRoaXMgbm9kZSAqLwo+ICugoKCgoKCg oKCgoKCgoKBlbnRyeSA9IDA7Cj4gKwo+ICugoKCgoKCgoKCgoKCgoKB0cmFjZV9hZGRyID0gY2Jl X3JlYWRfcG0oY3B1LCB0cmFjZV9hZGRyZXNzKTsKPiAroKCgoKCgoKCgoKCgoKCgd2hpbGUgKCh0 cmFjZV9hZGRyICYgQ0JFX1BNX1RSQUNFX0JVRl9FTVBUWSkgIT0gMHg0MDApCj4gK6CgoKCgoKCg oKCgoKCgoHsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAvKiB0aGVyZSBpcyBkYXRhIGluIHRo ZSB0cmFjZSBidWZmZXIgdG8gcHJvY2VzcyAqLwo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoGNi ZV9yZWFkX3RyYWNlX2J1ZmZlcihjcHUsIHRyYWNlX2J1ZmZlcik7IKAKPiAroKCgoKCgoKCgoKCg oKCgoKCgoKCgoKBzcHVfbWFzayA9IDB4RkZGRjAwMDAwMDAwMDAwMDsKPiArCj4gK6CgoKCgoKCg oKCgoKCgoKCgoKCgoKCgLyogRWFjaCBTUFUgUEMgaXMgMTYgYml0czsgaGVuY2UsIGZvdXIgc3B1 cyBpbiBlYWNoIG9mIAo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCAqIHRoZSB0d28gNjQtYml0 IGJ1ZmZlciBlbnRyaWVzIHRoYXQgbWFrZSB1cCB0aGUKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCg oKAgKiAxMjgtYml0IHRyYWNlX2J1ZmZlciBlbnRyeS4goFByb2Nlc3MgdGhlIHVwcGVyIGFuZAo+ ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCAqIGxvd2VyIDY0LWJpdCB2YWx1ZXMgc2ltdWx0YW5l b3VzbHkuCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgICovCj4gK6CgoKCgoKCgoKCgoKCgoKCg oKCgoKCgZm9yIChzcHUgPSAwOyBzcHUgPCBTUFVTX1BFUl9UQl9FTlRSWTsgc3B1KyspIHsKPiAr oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoHNwdV9wY19sb3dlciA9IHNwdV9tYXNrICYg dHJhY2VfYnVmZmVyWzBdOwo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgc3B1X3Bj X2xvd2VyID0gc3B1X3BjX2xvd2VyID4+IChOVU1fU1BVX0JJVFNfVFJCVUYKPiAroKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgKiAo U1BVU19QRVJfVEJfRU5UUlktc3B1LTEpKTsKPiArCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKBzcHVfcGNfdXBwZXIgPSBzcHVfbWFzayAmIHRyYWNlX2J1ZmZlclsxXTsKPiAroKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoHNwdV9wY191cHBlciA9IHNwdV9wY191cHBlciA+ PiAoTlVNX1NQVV9CSVRTX1RSQlVGCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCogKFNQVVNfUEVSX1RCX0VOVFJZLXNwdS0x KSk7Cj4gKwo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgc3B1X21hc2sgPSBzcHVf bWFzayA+PiBOVU1fU1BVX0JJVFNfVFJCVUY7Cj4gKwo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgLyogc3B1IFBDIHRyYWNlIGVudHJ5IGlzIHVwcGVyIDE2IGJpdHMgb2YgdGhlCj4g K6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgKiAxOCBiaXQgU1BVIHByb2dyYW0gY291 bnRlciAKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCAqLwo+ICugoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgc3B1X3BjX2xvd2VyID0gc3B1X3BjX2xvd2VyIDw8IDI7Cj4g K6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBzcHVfcGNfdXBwZXIgPSBzcHVfcGNfdXBw ZXIgPDwgMjsKPiArCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBzYW1wbGVzWygo bm9kZV9mYWN0b3IgKyBzcHUpICogVFJBQ0VfQVJSQVlfU0laRSkgKyBlbnRyeV0KPiAroKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgPSAodTMyKSBzcHVfcGNfbG93ZXI7Cj4g K6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBzYW1wbGVzWygobm9kZV9mYWN0b3IgKyBz cHUgKyBTUFVTX1BFUl9UQl9FTlRSWSkgKiBUUkFDRV9BUlJBWV9TSVpFKSArIGVudHJ5XQo+ICug oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKA9ICh1MzIpIHNwdV9wY191cHBl cjsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB9Cj4gKwo+ICugoKCgoKCgoKCgoKCgoKCgoKCg oKCgoGVudHJ5Kys7Cj4gKwo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoGlmIChlbnRyeSA+PSBU UkFDRV9BUlJBWV9TSVpFKSAKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoC8qIHNw dV9zYW1wbGVzIGlzIGZ1bGwgKi8KPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoGJy ZWFrOwo+ICsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB0cmFjZV9hZGRyID0gY2JlX3JlYWRf cG0oY3B1LCB0cmFjZV9hZGRyZXNzKTsKPiAroKCgoKCgoKCgoKCgoKCgfQo+ICugoKCgoKCgoKCg oKCgoKBzYW1wbGVzX3Blcl9ub2RlW25vZGVdID0gZW50cnk7Cj4gK6CgoKCgoKB9Cj4gK30KCldo aWxlIEkgY2FuJ3Qgc2VlIGFueXRoaW5nIHRlY2huaWNhbGx5IHdyb25nIHdpdGggdGhpcyBmdW5j dGlvbiwgaXQgd291bGQgYmUKZ29vZCB0byBzcGxpdCBpdCBpbnRvIHNtYWxsZXIgZnVuY3Rpb25z LiBTaW5jZSB5b3UgYXJlIG5lc3RpbmcgdGhyZWUKbG9vcHMsIGl0IHNob3VsZCBiZSBwb3NzaWJs ZSB0byBtYWtlIGEgc2VwYXJhdGUgZnVuY3Rpb24gZnJvbSBvbmUgb2YgdGhlCmlubmVyIGxvb3Bz IHdpdGhvdXQgY2hhbmdpbmcgdGhlIGFjdHVhbCBsb2dpYyBiZWhpbmQgaXQuCgo+ICsKPiArc3Rh dGljIGludCBwcm9maWxlX3NwdXMoc3RydWN0IGhydGltZXIgKiB0aW1lcikKPiArewo+ICugoKCg oKCga3RpbWVfdCBrdDsKPiArIKAgoCCgIKBpbnQgY3B1LCBub2RlLCBrLCBudW1fc2FtcGxlcywg c3B1X251bTsKCndoaXRlc3BhY2UgZGFtYWdlCgo+ICugoKCgoKCgCj4gK6CgoKCgoKBpZiAoIXNw dV9wcm9mX3J1bm5pbmcpCj4gK6CgoKCgoKCgoKCgoKCgoGdvdG8gU1RPUDsKPiArCj4gK6CgoKCg oKBjZWxsX3NwdV9wY19jb2xsZWN0aW9uKCk7Cj4gK6CgoKCgoKBmb3JfZWFjaF9vbmxpbmVfY3B1 KGNwdSkgewo+ICugoKCgoKCgoKCgoKCgoKBpZiAoY2JlX2dldF9od190aHJlYWRfaWQoY3B1KSkK PiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBjb250aW51ZTsKCkhlcmUsIHlvdSBlbnRlciB0aGUg c2FtZSB0b3AtbGV2ZWwgbG9vcCBhZ2Fpbiwgd2h5IG5vdCBtYWtlIGl0Cglmb3JfZWFjaF9vbmxp bmVfY3B1KGNwdSkgewoJCWlmIChjYmVfZ2V0X2h3X3RocmVhZF9pZChjcHUpKQogICAgICAgICAg ICAgICAgICAgICAgICAgY29udGludWU7CgkJbnVtX3NhbXBsZXMgPSBjZWxsX3NwdV9wY19jb2xs ZWN0aW9uKGNwdSk7CgkJLi4uCgo+ICugoKCgoKCga3QgPSBrdGltZV9zZXQoMCwgcHJvZmlsaW5n X2ludGVydmFsKTsKPiAroKCgoKCgoGlmICghc3B1X3Byb2ZfcnVubmluZykKPiAroKCgoKCgoKCg oKCgoKCgZ290byBTVE9QOwo+ICugoKCgoKCgaHJ0aW1lcl9mb3J3YXJkKHRpbWVyLCB0aW1lci0+ YmFzZS0+Z2V0X3RpbWUoKSwga3QpOwo+ICugoKCgoKCgcmV0dXJuIEhSVElNRVJfUkVTVEFSVDsK CmlzIGhydGltZXJfZm9yd2FyZCByZWFsbHkgdGhlIHJpZ2h0IGludGVyZmFjZSBoZXJlPyBZb3Ug YXJlIGlnbm9yaW5nCnRoZSBudW1iZXIgb2Ygb3ZlcnJ1bnMgYW55d2F5LCBzbyBocnRpbWVyX3N0 YXJ0KCwsKSBzb3VuZHMgbW9yZQpjb3JyZWN0IHRvIG1lLgoKPiArCj4gKyBTVE9QOgoKbGFiZWxz IHNob3VsZCBiZSBpbiBzbWFsbCBsZXR0ZXJzLgoKPiAroKCgoKCgoHByaW50ayhLRVJOX0lORk8g IlNQVV9QUk9GOiBzcHUtcHJvZiB0aW1lciBlbmRpbmdcbiIpOwo+ICugoKCgoKCgcmV0dXJuIEhS VElNRVJfTk9SRVNUQVJUOwo+ICt9Cgo+ICt2b2lkIHN0YXJ0X3NwdV9wcm9maWxpbmcodW5zaWdu ZWQgaW50IGN5Y2xlc19yZXNldCkgewo+ICsKPiAroKCgoKCgoGt0aW1lX3Qga3Q7Cj4gKwo+ICsg oCCgIKAgoC8qIFRvIGNhbGN1bGF0ZSBhIHRpbWVvdXQgaW4gbmFub3NlY29uZHMsIHRoZSBiYXNp Ywo+ICugoKCgoKCgICogZm9ybXVsYSBpcyBucyA9IGN5Y2xlc19yZXNldCAqIChOU0VDX1BFUl9T RUMgLyBjcHUgZnJlcXVlbmN5KS4KPiAroKCgoKCgoCAqIFRvIGF2b2lkIGZsb2F0aW5nIHBvaW50 IG1hdGgsIHdlIHVzZSB0aGUgc2NhbGUgbWF0aAo+ICugoKCgoKCgICogdGVjaG5pcXVlIGFzIGRl c2NyaWJlZCBpbiBsaW51eC9qaWZmaWVzLmguIKBXZSB1c2UKPiAroKCgoKCgoCAqIGEgc2NhbGUg ZmFjdG9yIG9mIFNDQUxFX1NISUZULHdoaWNoIHByb3ZpZGVzIDQgZGVjaW1hbCBwbGFjZXMKPiAr oKCgoKCgoCAqIG9mIHByZWNpc2lvbiwgd2hpY2ggaXMgY2xvc2UgZW5vdWdoIGZvciB0aGUgcHVy cG9zZSBhdCBoYW5kLgo+ICugoKCgoKCgICovCj4gKwo+ICugoKCgoKCgLyogU2luY2UgY3B1ZnJl cV9xdWlja19nZXQgcmV0dXJucyBmcmVxdWVuY3kgaW4ga0h6LCB3ZSB1c2UKPiAroKCgoKCgoCAq IFVTRUNfUEVSX1NFQyBoZXJlIHZzIE5TRUNfUEVSX1NFQy4KPiAroKCgoKCgoCAqLwo+ICugoKCg oKCgdW5zaWduZWQgbG9uZyBuc1BlckN5YyA9IChVU0VDX1BFUl9TRUMgPDwgU0NBTEVfU0hJRlQp L2toemZyZXE7Cj4gK6CgoKCgoKBwcm9maWxpbmdfaW50ZXJ2YWwgPSAobnNQZXJDeWMgKiBjeWNs ZXNfcmVzZXQpID4+IFNDQUxFX1NISUZUOwo+ICugoKCgoKCgCj4gK6CgoKCgoKBwcl9kZWJ1Zygi dGltZXIgcmVzb2x1dGlvbjogJWx1XG4iLCAKPiAroKCgoKCgoKCgoKCgoKCgIFRJQ0tfTlNFQyk7 CgpEb24ndCB5b3UgbmVlZCB0byBhZGFwdCB0aGUgcHJvZmlsaW5nX2ludGVydmFsIGF0IHJ1biB0 aW1lLCB3aGVuIGNwdWZyZXEKY2hhbmdlcyB0aGUgY29yZSBmcmVxdWVuY3k/IFlvdSBzaG91bGQg cHJvYmFibHkgdXNlCmNwdWZyZXFfcmVnaXN0ZXJfbm90aWZpZXIoKSB0byB1cGRhdGUgdGhpcy4K Cj4gK6CgoKCgoKBrdCA9IGt0aW1lX3NldCgwLCBwcm9maWxpbmdfaW50ZXJ2YWwpOwo+ICugoKCg oKCgaHJ0aW1lcl9pbml0KCZ0aW1lciwgQ0xPQ0tfTU9OT1RPTklDLCBIUlRJTUVSX1JFTCk7Cj4g K6CgoKCgoKB0aW1lci5leHBpcmVzID0ga3Q7Cj4gK6CgoKCgoKB0aW1lci5mdW5jdGlvbiA9IHBy b2ZpbGVfc3B1czsKPiArCj4gKyCgIKAgoCCgLyogQWxsb2NhdGUgYXJyYXlzIGZvciBjb2xsZWN0 aW5nIFNQVSBQQyBzYW1wbGVzICovCj4gK6CgoKCgoKBzYW1wbGVzID0gKHUzMiAqKSBremFsbG9j KG51bV9ub2RlcyAqIFNQVVNfUEVSX05PREUgKiBUUkFDRV9BUlJBWV9TSVpFICogc2l6ZW9mKHUz MiksIEdGUF9BVE9NSUMpOwoKVHJ5IHRvIGF2b2lkIGF0b21pYyBhbGxvY2F0aW9ucy4gSSBkb24n dCB0aGluayB5b3UgYXJlIGluIGFuIGF0b21pYwpjb250ZXh0IGhlcmUgYXQgYWxsLCBzbyB5b3Ug Y2FuIGp1c3QgdXNlIEdGUF9LRVJORUwuCgo+ICugoKCgoKCgc2FtcGxlc19wZXJfbm9kZSA9ICh1 MzIgKikga3phbGxvYyhudW1fbm9kZXMgKiBzaXplb2YodTMyKSwgR0ZQX0FUT01JQyk7CgpTaW5j ZSBNQVhfTlVNTk9ERVMgaXMgc21hbGwsIGl0J3MgcHJvYmFibHkgbW9yZSBlZmZpY2llbnQgdG8g anVzdCBhbGxvY2F0ZSB0aGlzCnN0YXRpY2FsbHkuCgo+ICsKPiAroKCgoKCgoHNwdV9wcm9mX3J1 bm5pbmcgPSAxOwo+ICugoKCgoKCgaHJ0aW1lcl9zdGFydCgmdGltZXIsIGt0LCBIUlRJTUVSX1JF TCk7Cj4gK30KPgo+ICsKPiArdm9pZCBzdG9wX3NwdV9wcm9maWxpbmcodm9pZCkgCj4gK3sKPiAr Cj4gK6CgoKCgoKBocnRpbWVyX2NhbmNlbCgmdGltZXIpOwo+ICugoKCgoKCga2ZyZWUoc2FtcGxl cyk7Cj4gK6CgoKCgoKBrZnJlZShzYW1wbGVzX3Blcl9ub2RlKTsKPiAroKCgoKCgoHByX2RlYnVn KCJTUFVfUFJPRjogc3RvcF9zcHVfcHJvZmlsaW5nIGlzc3VlZFxuIik7Cj4gK6CgoKCgoKBzcHVf cHJvZl9ydW5uaW5nID0gMDsKPiArfQoKc2hvdWxkbid0IHlvdSBzZXQgc3B1X3Byb2ZfcnVubmlu ZyA9IDAgYmVmb3JlIGRvaW5nIGFueSBvZiB0aGUgb3RoZXIgdGhpbmdzPwpJdCBsb29rcyB0byBt ZSBsaWtlIHlvdSBjb3VsZCBvdGhlcndpc2UgZ2V0IGludG8gYSB1c2UtYWZ0ZXItZnJlZQpzaXR1 YXRpb24uIElmIEknbSB3cm9uZyB3aXRoIHRoYXQsIHlvdSBwcm9iYWJseSBkb24ndCBuZWVkIHNw dV9wcm9mX3J1bm5pbmcKYXQgYWxsIDstKQoKPiArLyogQ29uYWluZXIgZm9yIGNhY2hpbmcgaW5m b3JtYXRpb24gYWJvdXQgYW4gYWN0aXZlIFNQVSB0YXNrLgo+ICsgKiCgIDptYXAgLS0gcG9pbnRl ciB0byBhIGxpc3Qgb2Ygdm1hX21hcHMKPiArICogoCA6c3B1IC0tIHRoZSBzcHUgZm9yIHRoaXMg YWN0aXZlIFNQVSB0YXNrCj4gKyAqIKAgOmxpc3QgLS0gcG90ZW50aWFsbHkgY291bGQgYmUgdXNl ZCB0byBjb250YWluIHRoZSBjYWNoZWRfaW5mb3MKPiArICogoCCgIKAgoCCgIKBmb3IgaW5hY3Rp dmUgU1BVIHRhc2tzLgoKRG9jdW1lbnRpbmcgc3RydWN0dXJlcyBpcyBnb29kLCBidXQgcGxlYXNl IHVzZSB0aGUgY29tbW9uIGtlcm5lbGRvYyBmb3JtYXQKZm9yIGl0LiBUaGVyZSBhcmUgYSBudW1i ZXIgb2YgZXhhbXBsZXMgZm9yIHRoaXMgaW4gaW5jbHVkZS9saW51eC8KCj4gKyAqIAo+ICsgKiBJ ZGVhbGx5LCB3ZSB3b3VsZCBsaWtlIHRvIGJlIGFibGUgdG8gY3JlYXRlIHRoZSBjYWNoZWRfaW5m byBmb3IKPiArICogYW4gU1BVIHRhc2sganVzdCBvbmUgdGltZSAtLSB3aGVuIGxpYnNwZSBmaXJz dCBsb2FkcyB0aGUgU1BVIAo+ICsgKiBiaW5hcnkgZmlsZS4goFdlIHdvdWxkIHN0b3JlIHRoZSBj YWNoZWRfaW5mbyBpbiBhIGxpc3QuIKBUaGVuLCBhcwo+ICsgKiBTUFUgdGFza3MgYXJlIHN3aXRj aGVkIG91dCBhbmQgbmV3IG9uZXMgc3dpdGNoZWQgaW4sIHRoZSBjYWNoZWRfaW5mbwo+ICsgKiBm b3IgaW5hY3RpdmUgdGFza3Mgd291bGQgYmUga2VwdCwgYW5kIHRoZSBhY3RpdmUgb25lIHdvdWxk IGJlIHBsYWNlZAo+ICsgKiBhdCB0aGUgaGVhZCBvZiB0aGUgbGlzdC4goEJ1dCB0aGlzIHRlY2hu aXF1ZSBtYXkgbm90IHdpdGgKPiArICogY3VycmVudCBzcHVmcyBmdW5jdGlvbmFsaXR5IHNpbmNl IHRoZSBzcHUgdXNlZCBpbiBiaW5kX2NvbnRleHQgbWF5Cj4gKyAqIGJlIGEgZGlmZmVyZW50IHNw dSB0aGFuIHdhcyB1c2VkIGluIGEgcHJldmlvdXMgYmluZF9jb250ZXh0IGZvciBhCj4gKyAqIHJl YWN0aXZhdGVkIFNQVSB0YXNrLiCgQWRkaXRpb25hbGx5LCBhIHJlYWN0aXZhdGVkIFNQVSB0YXNr IG1heSBiZQo+ICsgKiBhc3NpZ25lZCB0byBydW4gb24gYSBkaWZmZXJlbnQgcGh5c2ljYWwgU1BF LiCgV2Ugd2lsbCBpbnZlc3RpZ2F0ZQo+ICsgKiBmdXJ0aGVyIGlmIHRoaXMgY2FuIGJlIGRvbmUu Cj4gKyAqCj4gKyAqLwoKWW91IHNob3VsZCBzdHVmZiBhIHBvaW50ZXIgdG8gY2FjaGVkX2luZm8g aW50byBzdHJ1Y3Qgc3B1X2NvbnRleHQsCmUuZy4gJ3ZvaWQgKnByb2ZpbGVfcHJpdmF0ZScuCgo+ ICtzdHJ1Y3QgY2FjaGVkX2luZm8gewo+ICugoKCgoKCgdm1hX21hcF90ICogbWFwOwo+ICugoKCg oKCgc3RydWN0IHNwdSAqIHRoZV9zcHU7Cj4gK6CgoKCgoKBzdHJ1Y3Qga3JlZiBjYWNoZV9yZWY7 Cj4gK6CgoKCgoKBzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7Cj4gK307CgpBbmQgcmVwbGFjZSB0aGUg J3RoZV9zcHUnIG1lbWJlciB3aXRoIGEgYmFjayBwb2ludGVyIHRvIHRoZQpzcHVfY29udGV4dCBp ZiB5b3UgbmVlZCBpdC4KCj4gKwo+ICsvKiBBIGRhdGEgc3RydWN0dXJlIGZvciBjYWNoZWQgaW5m b3JtYXRpb24gYWJvdXQgYWN0aXZlIFNQVSB0YXNrcy4KPiArICogU3RvcmFnZSBpcyBkeW5hbWlj YWxseSBhbGxvY2F0ZWQsIHNpemVkIGFzCj4gKyAqICJudW1iZXIgb2YgYWN0aXZlIG5vZGVzIG11 bHRwbGllZCBieSA4Ii4gCj4gKyAqIFRoZSBpbmZvX2xpc3Rbbl0gbWVtYmVyIGhvbGRzIDAgb3Ig bW9yZSAKPiArICogJ3N0cnVjdCBjYWNoZWRfaW5mbycgb2JqZWN0cyBmb3IgU1BVIz1uLiAKPiAr ICoKPiArICogQXMgY3VycmVudGx5IGltcGxlbWVudGVkLCB0aGVyZSB3aWxsIG9ubHkgZXZlciBi ZSBvbmUgY2FjaGVkX2luZm8gCj4gKyAqIGluIHRoZSBsaXN0IGZvciBhIGdpdmVuIFNQVS4goElm IHdlIGNhbiBkZXZpc2UgYSB3YXkgdG8gbWFpbnRhaW4KPiArICogbXVsdGlwbGUgY2FjaGVkX2lu Zm9zIGluIG91ciBsaXN0LCB0aGVuIGl0IHdvdWxkIG1ha2Ugc2Vuc2UKPiArICogdG8gYWxzbyBj YWNoZSB0aGUgZGNvb2tpZSByZXByZXNlbnRpbmcgdGhlIFBQVSB0YXNrIGFwcGxpY2F0aW9uLgo+ ICsgKiBTZWUgYWJvdmUgZGVzY3JpcHRpb24gb2Ygc3RydWN0IGNhY2hlZF9pbmZvIGZvciBtb3Jl IGRldGFpbHMuCj4gKyAqLwo+ICtzdHJ1Y3Qgc3B1X2luZm9fc3RhY2tzIHsKPiAroKCgoKCgoHN0 cnVjdCBsaXN0X2hlYWQgKiBpbmZvX2xpc3Q7Cj4gK307CgpXaHkgZG8geW91IHN0b3JlIHBvaW50 ZXJzIHRvIGxpc3RfaGVhZCBzdHJ1Y3R1cmVzPyBJZiB5b3Ugd2FudCB0byBzdG9yZQpsaXN0cywg eW91IHNob3VsZCBoYXZlIGEgbGlzdHNfaGVhZCBpdHNlbGYgaW4gaGVyZS4KCldoeSBkbyB5b3Ug c3RvcmUgdGhlbSBwZXIgc3B1IGluIHRoZSBmaXJzdCBwbGFjZT8gVGhlIHBoeXNpY2FsIHNwdQpk b2Vzbid0IGhhdmUgYW55IHJlbGV2YW5jZSB0byB0aGlzIGF0IGFsbCwgdGhlIG9ubHkgZGF0YSB0 aGF0IGlzCnBlciBzcHUgaXMgdGhlIHNhbXBsZSBkYXRhIGNvbGxlY3RlZCBvbiBhIHByb2ZpbGlu ZyBpbnRlcnJ1cHQsCndoaWNoIHlvdSBjYW4gdGhlbiBjb3B5IGluIHRoZSBwZXItY29udGV4dCBk YXRhIG9uIGEgY29udGV4dCBzd2l0Y2guCgoKPiArLyogTG9va3MgZm9yIGNhY2hlZCBpbmZvIGZv ciB0aGUgcGFzc2VkIHNwdS4goElmIG5vdCBmb3VuZCwgdGhlCj4gKyAqIGNhY2hlZCBpbmZvIGlz IGNyZWF0ZWQgZm9yIHRoZSBwYXNzZWQgc3B1Lgo+ICsgKiBSZXR1cm5zIDAgZm9yIHN1Y2Nlc3M7 IG90aGVyd2lzZSwgLTEgZm9yIGVycm9yLiCgCj4gKyAqLyAKPiArc3RhdGljIGludAo+ICtwcmVw YXJlX2NhY2hlZF9zcHVfaW5mbyhzdHJ1Y3Qgc3B1ICogc3B1LCB1bnNpZ25lZCBpbnQgb2JqZWN0 SWQpCj4gK3sKCnNlZSBhYm92ZSwgdGhpcyBzaG91bGQgZ2V0IHRoZSBzcHVfY29udGV4dCBwb2lu dGVyIGFzIGl0cyBhcmd1bWVudCwKbm90IHRoZSBzcHUuCgo+ICugoKCgoKCgdm1hX21hcF90ICog bmV3X21hcDsKPiAroKCgoKCgoHVuc2lnbmVkIGxvbmcgZmxhZ3MgPSAwOwo+ICugoKCgoKCgaW50 IHJldHZhbCA9IDA7Cj4gK6CgoKCgoKAvKiBzcHUtPm51bWJlciBpcyBhIHN5c3RlbS13aWRlIHZh bHVlLCBub3QgYSBwZXItbm9kZSB2YWx1ZS4gKi8KPiAroKCgoKCgoHN0cnVjdCBjYWNoZWRfaW5m byAqIGluZm8gPSBnZXRfY2FjaGVkX2luZm8oc3B1LT5udW1iZXIpOwo+ICugoKCgoKCgaWYgKGlu Zm8gPT0gTlVMTCkgewoKaWYgeW91IHJldmVydCB0aGUgbG9naWMgdG8KCglpZiAoaW5mbykKCQln b3RvIG91dDsKCnRoZW4gdGhlIGJ1bGsgb2YgeW91ciBmdW5jdGlvbiBkb2Vzbid0IG5lZWQgdG8g Z2V0IGluZGVudGVkLAp3aGljaCBoZWxwcyByZWFkYWJpbGl0eS4KCj4gK6CgoKCgoKCgoKCgoKCg oC8qIGNyZWF0ZSBjYWNoZWRfaW5mbyBhbmQgYWRkIGl0IHRvIHRoZSBsaXN0IGZvciBTUFUgIzxu Pi4qLwo+ICugoKCgoKCgoKCgoKCgoKBpbmZvID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IGNhY2hl ZF9pbmZvKSwgR0ZQX0FUT01JQyk7CgpHRlBfS0VSTkVMCgo+ICugoKCgoKCgoKCgoKCgoKBpZiAo IWluZm8pIHsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBwcmludGsoS0VSTl9FUlIgIlNQVV9Q Uk9GOiAiCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIKAgoCCgICIlcywgbGluZSAlZDogY3Jl YXRlIHZtYV9tYXAgZmFpbGVkXG4iLAo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCCgIKAgoCBf X0ZVTkNUSU9OX18sIF9fTElORV9fKTsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBnb3RvIEVS Ul9BTExPQzsKPiAroKCgoKCgoKCgoKCgoKCgfQo+ICugoKCgoKCgoKCgoKCgoKBuZXdfbWFwID0g Y3JlYXRlX3ZtYV9tYXAoc3B1LCBvYmplY3RJZCk7Cj4gK6CgoKCgoKCgoKCgoKCgoGlmICghbmV3 X21hcCkgewo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoHByaW50ayhLRVJOX0VSUiAiU1BVX1BS T0Y6ICIKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgoCCgIKAgIiVzLCBsaW5lICVkOiBjcmVh dGUgdm1hX21hcCBmYWlsZWRcbiIsCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIKAgoCCgIF9f RlVOQ1RJT05fXywgX19MSU5FX18pOwo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoGdvdG8gRVJS X0FMTE9DOwo+ICugoKCgoKCgoKCgoKCgoKB9Cj4gKwo+ICugoKCgoKCgoKCgoKCgoKBwcl9kZWJ1 ZygiQ3JlYXRlZCB2bWFfbWFwXG4iKTsKPiArIKCgoKCgoKCgoKCgoKCgaW5mby0+bWFwID0gbmV3 X21hcDsKPiAroKCgoKCgoKCgoKCgoKCgaW5mby0+dGhlX3NwdSA9IHNwdTsKPiAroKCgoKCgoKCg oKCgoKCga3JlZl9pbml0KCZpbmZvLT5jYWNoZV9yZWYpOwo+ICugoKCgoKCgoKCgoKCgoKBzcGlu X2xvY2tfaXJxc2F2ZSgmY2FjaGVfbG9jaywgZmxhZ3MpOwo+ICugoKCgoKCgoKCgoKCgoKBsaXN0 X2FkZCgmaW5mby0+bGlzdCwgJnNwdV9pbmZvLT5pbmZvX2xpc3Rbc3B1LT5udW1iZXJdKTsKPiAr oKCgoKCgoKCgoKCgoKCgc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY2FjaGVfbG9jaywgZmxhZ3Mp Owo+ICugoKCgoKCgoKCgoKCgoKBnb3RvIE9VVDsKPiAroKCgoKCgoH0gZWxzZSB7Cj4gKyCgIKAg oCCgLyogSW1tZWRpZGF0ZWx5IHB1dCBiYWNrIHJlZmVyZW5jZSB0byBjYWNoZWRfaW5mbyBzaW5j ZSB3ZSBkb24ndAo+ICugoKCgoKCgICogcmVhbGx5IG5lZWQgaXQgLS0ganVzdCBjaGVja2luZyB3 aGV0aGVyIHdlIGhhdmUgaXQuCj4gK6CgoKCgoKAgKi8KPiAroKCgoKCgoKCgoKCgoKCgcHV0X2Nh Y2hlZF9pbmZvKGluZm8pOwo+ICugoKCgoKCgoKCgoKCgoKBwcl9kZWJ1ZygiRm91bmQgY2FjaGVk IFNQVSBpbmZvLlxuIik7Cj4gK6CgoKCgoKB9Cj4gK6CgoKCgoKAKPiArRVJSX0FMTE9DOgo+ICug oKCgoKCgcmV0dmFsID0gLTE7Cj4gK09VVDoKPiAroKCgoKCgoHJldHVybiByZXR2YWw7Cj4gK30K Cj4gKy8qIExvb2sgdXAgdGhlIGRjb29raWUgZm9yIHRoZSB0YXNrJ3MgZmlyc3QgVk1fRVhFQ1VU QUJMRSBtYXBwaW5nLAo+ICsgKiB3aGljaCBjb3JyZXNwb25kcyBsb29zZWx5IHRvICJhcHBsaWNh dGlvbiBuYW1lIi4gQWxzbywgZGV0ZXJtaW5lCj4gKyAqIHRoZSBvZmZzZXQgZm9yIHRoZSBTUFUg RUxGIG9iamVjdC4goElmIGNvbXB1dGVkIG9mZnNldCBpcyAKPiArICogbm9uLXplcm8sIGl0IGlt cGxpZXMgYW4gZW1iZWRkZWQgU1BVIG9iamVjdDsgb3RoZXJ3aXNlLCBpdCdzIGEKPiArICogc2Vw YXJhdGUgU1BVIGJpbmFyeSwgaW4gd2hpY2ggY2FzZSB3ZSByZXRyaWV2ZSBpdCdzIGRjb29raWUu Cj4gKyAqLwo+ICtzdGF0aWMgdW5zaWduZWQgbG9uZyAKPiArZ2V0X2V4ZWNfZGNvb2tpZV9hbmRf b2Zmc2V0KAo+ICugoKCgoKCgc3RydWN0IHNwdSAqIHNwdSwgdW5zaWduZWQgaW50ICogb2Zmc2V0 cCwKPiAroKCgoKCgoHVuc2lnbmVkIGxvbmcgKiBzcHVfYmluX2Rjb29raWUsCj4gK6CgoKCgoKB1 bnNpZ25lZCBpbnQgc3B1X3JlZikKPiArewo+ICsgoCCgIKAgoHVuc2lnbmVkIGxvbmcgY29va2ll ID0gMDsKPiAroKCgoKCgoHVuc2lnbmVkIGludCBteV9vZmZzZXQgPSAwOwo+ICsgoCCgIKAgoHN0 cnVjdCB2bV9hcmVhX3N0cnVjdCAqIHZtYTsKPiAroKCgoKCgoHN0cnVjdCBtbV9zdHJ1Y3QgKiBt bSA9IHNwdS0+bW07CgppbmRlbnRpbmcKCj4gKyCgIKAgoCCgaWYgKCFtbSkKPiArIKAgoCCgIKAg oCCgIKAgoGdvdG8gT1VUOwo+ICsKPiArIKAgoCCgIKBmb3IgKHZtYSA9IG1tLT5tbWFwOyB2bWE7 IHZtYSA9IHZtYS0+dm1fbmV4dCkgewo+ICsgoCCgIKAgoCCgIKAgoCCgaWYgKCF2bWEtPnZtX2Zp bGUpCj4gKyCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoGNvbnRpbnVlOwo+ICsgoCCgIKAgoCCgIKAg oCCgaWYgKCEodm1hLT52bV9mbGFncyAmIFZNX0VYRUNVVEFCTEUpKQo+ICsgoCCgIKAgoCCgIKAg oCCgIKAgoCCgIKBjb250aW51ZTsKPiArIKAgoCCgIKAgoCCgIKAgoGNvb2tpZSA9IGZhc3RfZ2V0 X2Rjb29raWUodm1hLT52bV9maWxlLT5mX2RlbnRyeSwKPiArIKAgoCCgIKAgoCCgIKAgoCCgIKAg oCCgdm1hLT52bV9maWxlLT5mX3Zmc21udCk7Cj4gK6CgoKCgoKCgoKCgoKCgoHByX2RlYnVnKCJn b3QgZGNvb2tpZSBmb3IgJXNcbiIsCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIKB2bWEtPnZt X2ZpbGUtPmZfZGVudHJ5LT5kX25hbWUubmFtZSk7Cj4gKyCgIKAgoCCgIKAgoCCgIKBicmVhazsK PiArIKAgoCCgIKB9Cj4gKwo+ICugoKCgoKCgZm9yICh2bWEgPSBtbS0+bW1hcDsgdm1hOyB2bWEg PSB2bWEtPnZtX25leHQpIHsKPiAroKCgoKCgoKCgoKCgoKCgaWYgKHZtYS0+dm1fc3RhcnQgPiBz cHVfcmVmIHx8IHZtYS0+dm1fZW5kIDwgc3B1X3JlZikKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCg oKBjb250aW51ZTsKPiAroKCgoKCgoKCgoKCgoKCgbXlfb2Zmc2V0ID0gc3B1X3JlZiAtIHZtYS0+ dm1fc3RhcnQ7Cj4gK6CgoKCgoKCgoKCgoKCgoHByX2RlYnVnKCJGb3VuZCBzcHUgRUxGIGF0ICIK PiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgoCIgJVggZm9yIGZpbGUgJXNcbiIsIG15X29mZnNl dCwKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgoHZtYS0+dm1fZmlsZS0+Zl9kZW50cnktPmRf bmFtZS5uYW1lKTsKPiAroKCgoKCgoKCgoKCgoKCgKm9mZnNldHAgPSBteV9vZmZzZXQ7Cj4gK6Cg oKCgoKCgoKCgoKCgoGlmIChteV9vZmZzZXQgPT0gMCkgewo+ICugoKCgoKCgoKCgoKCgoKCgoKCg oKCgoGlmICghdm1hLT52bV9maWxlKSB7Cj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKBnb3RvIEZBSUxfTk9fU1BVX0NPT0tJRTsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB9Cj4g K6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgKnNwdV9iaW5fZGNvb2tpZSA9IGZhc3RfZ2V0X2Rjb29r aWUoCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB2bWEtPnZtX2ZpbGUtPmZfZGVu dHJ5LAo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgdm1hLT52bV9maWxlLT5mX3Zm c21udCk7Cj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgcHJfZGVidWcoImdvdCBkY29va2llIGZv ciAlc1xuIiwKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCCgdm1hLT52bV9maWxl LT5mX2RlbnRyeS0+ZF9uYW1lLm5hbWUpOwo+ICugoKCgoKCgoKCgoKCgoKB9Cj4gK6CgoKCgoKCg oKCgoKCgoGJyZWFrOwo+ICugoKCgoKCgfQo+ICugoKCgoKCgCj4gK09VVDoKPiArIKAgoCCgIKBy ZXR1cm4gY29va2llOwo+ICsKPiArRkFJTF9OT19TUFVfQ09PS0lFOgo+ICugoKCgoKCgcHJpbnRr KEtFUk5fRVJSICJTUFVfUFJPRjogIgo+ICugoKCgoKCgIKAgoCCgICIlcywgbGluZSAlZDogQ2Fu bm90IGZpbmQgZGNvb2tpZSBmb3IgU1BVIGJpbmFyeVxuIiwKPiAroKCgoKCgoCCgIKAgoCBfX0ZV TkNUSU9OX18sIF9fTElORV9fKTsKPiAroKCgoKCgoGdvdG8gT1VUOwo+ICt9Cj4gKwo+ICsKPiAr Cj4gKy8qIFRoaXMgZnVuY3Rpb24gZmluZHMgb3IgY3JlYXRlcyBjYWNoZWQgY29udGV4dCBpbmZv cm1hdGlvbiBmb3IgdGhlCj4gKyAqIHBhc3NlZCBTUFUgYW5kIHJlY29yZHMgU1BVIGNvbnRleHQg aW5mb3JtYXRpb24gaW50byB0aGUgT1Byb2ZpbGUKPiArICogZXZlbnQgYnVmZmVyLgo+ICsgKi8K PiArc3RhdGljIGludCBwcm9jZXNzX2NvbnRleHRfc3dpdGNoKHN0cnVjdCBzcHUgKiBzcHUsIHVu c2lnbmVkIGludCBvYmplY3RJZCkKPiArewo+ICugoKCgoKCgdW5zaWduZWQgbG9uZyBmbGFncyA9 IDA7Cj4gK6CgoKCgoKBpbnQgcmV0dmFsID0gMDsKPiAroKCgoKCgoHVuc2lnbmVkIGludCBvZmZz ZXQgPSAwOwo+ICugoKCgoKCgdW5zaWduZWQgbG9uZyBzcHVfY29va2llID0gMCwgYXBwX2Rjb29r aWUgPSAwOwo+ICugoKCgoKCgcmV0dmFsID0gcHJlcGFyZV9jYWNoZWRfc3B1X2luZm8oc3B1LCBv YmplY3RJZCk7Cj4gK6CgoKCgoKBpZiAocmV0dmFsID09IC0xKSB7Cj4gK6CgoKCgoKCgoKCgoKCg oGdvdG8gT1VUOwo+ICugoKCgoKCgfQo+ICsgoCCgIKAgoC8qIEdldCBkY29va2llIGZpcnN0IGJl Y2F1c2UgYSBtdXRleF9sb2NrIGlzIHRha2VuIGluIHRoYXQKPiAroKCgoKCgoCAqIGNvZGUgcGF0 aCwgc28gaW50ZXJydXB0cyBtdXN0IG5vdCBiZSBkaXNhYmxlZC4KPiAroKCgoKCgoCAqLwo+ICug oKCgoKCgYXBwX2Rjb29raWUgPSBnZXRfZXhlY19kY29va2llX2FuZF9vZmZzZXQoc3B1LCAmb2Zm c2V0LCAKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAg oCZzcHVfY29va2llLCBvYmplY3RJZCk7Cj4gKwo+ICsgoCCgIKAgoC8qIFJlY29yZCBjb250ZXh0 IGluZm8gaW4gZXZlbnQgYnVmZmVyICovCj4gK6CgoKCgoKBzcGluX2xvY2tfaXJxc2F2ZSgmYnVm ZmVyX2xvY2ssIGZsYWdzKTsKPiAroKCgoKCgoGFkZF9ldmVudF9lbnRyeShFU0NBUEVfQ09ERSk7 Cj4gK6CgoKCgoKBhZGRfZXZlbnRfZW50cnkoU1BVX0NUWF9TV0lUQ0hfQ09ERSk7Cj4gK6CgoKCg oKBhZGRfZXZlbnRfZW50cnkoc3B1LT5udW1iZXIpOwo+ICugoKCgoKCgYWRkX2V2ZW50X2VudHJ5 KHNwdS0+cGlkKTsKPiAroKCgoKCgoGFkZF9ldmVudF9lbnRyeShzcHUtPnRnaWQpOwo+ICugoKCg oKCgYWRkX2V2ZW50X2VudHJ5KGFwcF9kY29va2llKTsKPiArCj4gK6CgoKCgoKBhZGRfZXZlbnRf ZW50cnkoRVNDQVBFX0NPREUpOwo+ICugoKCgoKCgaWYgKG9mZnNldCkgewo+ICugoKCgoKCgIKAv KiBXaGVuIG9mZnNldCBpcyBub24temVybywgoHRoaXMgbWVhbnMgdGhlIFNQVSBFTEYgd2FzIGVt YmVkZGVkOwo+ICugoKCgoKCgIKAgKiBvdGhlcndpc2UsIGl0IHdhcyBsb2FkZWQgZnJvbSBhIHNl cGFyYXRlIGJpbmFyeSBmaWxlLiCgRm9yIHRoZQo+ICugoKCgoKCgIKAgKiBlbWJlZGRlZCBjYXNl LCB3ZSByZWNvcmQgdGhlIG9mZnNldCBvZiB0aGUgU1BVIEVMRiBpbnRvIHRoZSBQUFUKPiAroKCg oKCgoCCgICogZXhlY3V0YWJsZTsgZm9yIHRoZSBub24tZW1iZWRkZWQgY2FzZSwgd2UgcmVjb3Jk IGEgZGNvb2tpZSB0aGF0Cj4gK6CgoKCgoKAgoCAqIHBvaW50cyB0byB0aGUgbG9jYXRpb24gb2Yg dGhlIFNQVSBiaW5hcnkgdGhhdCB3YXMgbG9hZGVkLgo+ICugoKCgoKCgIKAgKi8KPiAroKCgoKCg oKCgoKCgoKCgYWRkX2V2ZW50X2VudHJ5KFNQVV9PRkZTRVRfQ09ERSk7Cj4gK6CgoKCgoKCgoKCg oKCgoGFkZF9ldmVudF9lbnRyeShvZmZzZXQpOwo+ICugoKCgoKCgfSBlbHNlIHsKPiAroKCgoKCg oKCgoKCgoKCgYWRkX2V2ZW50X2VudHJ5KFNQVV9DT09LSUVfQ09ERSk7Cj4gK6CgoKCgoKCgoKCg oKCgoGFkZF9ldmVudF9lbnRyeShzcHVfY29va2llKTsKPiAroKCgoKCgoH0KCkkgZG9uJ3QgZ2V0 IGl0LiBXaGF0IGlzIHRoZSBhcHBfZGNvb2tpZSB1c2VkIGZvcj8gSWYgdGhlIHNwdSBiaW5hcnkg aXMKZW1iZWRkZWQgaW50byBhIGxpYnJhcnksIHlvdSBhcmUgc3RpbGwgbWlzc2luZyB0aGUgZGNv b2tpZSB0byB0aGF0IC5zbyBmaWxlLApiZWNhdXNlIHlvdSByZXR1cm4gb25seSBhbiBvZmZzZXQu Cgo8bml0cGlja2luZz4KCj4gK6CgoKCgoKB1bnNpZ25lZCBsb25nIGZsYWdzID0gMDsKCm5vIG5l ZWQgdG8gaW5pdGlhbGl6ZQoKPiAroKCgoKCgoHN0cnVjdCBzcHUgKiB0aGVfc3B1ID0gKHN0cnVj dCBzcHUgKikgZGF0YTsKCm5vIG5lZWQgZm9yIHRoZSBjYXN0Cgo+ICugoKCgoKCgcHJfZGVidWco IlNQVSBldmVudCBub3RpZmljYXRpb24gYXJyaXZlZFxuIik7Cj4gK6CgoKCgoKBpZiAodmFsID09 IDApewoKaWYgKCF2YWwpCgo+ICugoKCgoKCgcHJfZGVidWcoInNwdV9zeW5jX3N0YXJ0IC0tIHJ1 bm5pbmcuXG4iKTsKPiArT1VUOgoKb3V0OgoKPiAroKCgoKCgoHJldHVybiByZXQ7oKCgoKAKPiAr fQoKPC9uaXRwaWNraW5nPgoKCgo+IEBAIC00ODAsNyArNDkxLDIyIEBACj4goKCgoKCgoKAgoCCg IKAgc3RydWN0IG9wX3N5c3RlbV9jb25maWcgKnN5cywgaW50IG51bV9jdHJzKQo+IKB7Cj4goKCg oKCgoKBpbnQgaSwgaiwgY3B1Owo+ICugoKCgoKCgc3B1X2N5Y2xlX3Jlc2V0ID0gMDsKPiCgCj4g K6CgoKCgoKAvKiBUaGUgY3B1ZnJlcV9xdWlja19nZXQgZnVuY3Rpb24gcmVxdWlyZXMgdGhhdCBj YmVfY3B1ZnJlcSBtb2R1bGUKPiAroKCgoKCgoCAqIGJlIGxvYWRlZC4goFRoaXMgZnVuY3Rpb24g aXMgbm90IGFjdHVhbGx5IHByb3ZpZGVkIGFuZCBleHBvcnRlZAo+ICugoKCgoKCgICogYnkgY2Jl X2NwdWZyZXEsIGJ1dCBpdCByZWxpZXMgb24gY2JlX2NwdWZyZXEgaW5pdGlhbGl6ZSBrZXJuZWwK PiAroKCgoKCgoCAqIGRhdGEgc3RydWN0dXJlcy4goFNpbmNlIHRoZXJlJ3Mgbm8gd2F5IGZvciBk ZXBtb2QgdG8gcmVhbGl6ZQo+ICugoKCgoKCgICogdGhhdCBvdXIgT1Byb2ZpbGUgbW9kdWxlIGRl cGVuZHMgb24gY2JlX2NwdWZyZXEsIHdlIGN1cnJlbnRseQo+ICugoKCgoKCgICogYXJlIGxldHRp bmcgdGhlIHVzZXJzcGFjZSB0b29sLCBvcGNvbnRyb2wsIGVuc3VyZSB0aGF0IHRoZQo+ICugoKCg oKCgICogY2JlX2NwdWZyZXEgbW9kdWxlIGlzIGxvYWRlZC4KPiAroKCgoKCgoCAqLwo+ICugoKCg oKCga2h6ZnJlcSA9IGNwdWZyZXFfcXVpY2tfZ2V0KHNtcF9wcm9jZXNzb3JfaWQoKSk7CgpZb3Ug c2hvdWxkIHByb2JhYmx5IGhhdmUgYSBmYWxsYmFjayBpbiBoZXJlIGluIGNhc2UgdGhlIGNwdWZy ZXEgbW9kdWxlCmlzIG5vdCBsb2FkZWQuIFRoZXJlIGlzIGEgZ2xvYmFsIHZhcmlhYmxlIHBwY19w cm9jX2ZyZXEgKGluIEh6KSB0aGF0CnlvdSBjYW4gYWNjZXNzLgo+IKCgoKCgoKCgOwo+IKB9Cj4g oAo+IC1zdGF0aWMgdm9pZCBjZWxsX2dsb2JhbF9zdGFydChzdHJ1Y3Qgb3BfY291bnRlcl9jb25m aWcgKmN0cikKPiArc3RhdGljIGludCBjYWxjdWxhdGVfbGZzcihpbnQgbikKPiArewo+ICsjZGVm aW5lIHNpemUgMjQKPiAroKCgoKCgoGludCBpOwo+ICugoKCgoKCgdW5zaWduZWQgaW50IG5ld2xm c3IwOwo+ICugoKCgoKCgdW5zaWduZWQgaW50IGxmc3IgPSAweEZGRkZGRjsKPiAroKCgoKCgoHVu c2lnbmVkIGludCBob3dtYW55ID0gbGZzciAtIG47Cj4gKwo+ICugoKCgoKCgZm9yIChpID0gMjsg aSA8IGhvd21hbnkgKyAyOyBpKyspIHsKPiAroKCgoKCgoKCgoKCgoKCgbmV3bGZzcjAgPSAoKChs ZnNyID4+IChzaXplIC0gMSAtIDApKSAmIDEpIF4KPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAg oCCgKChsZnNyID4+IChzaXplIC0gMSAtIDEpKSAmIDEpIF4KPiAroKCgoKCgoKCgoKCgoKCgoKCg oKCgoKAgoCCgKCgobGZzciA+PiAoc2l6ZSAtIDEgLSA2KSkgJiAxKSBeCj4gK6CgoKCgoKCgoKCg oKCgoKCgoKCgoKCgIKAgoCAoKGxmc3IgPj4gKHNpemUgLSAxIC0gMjMpKSAmIDEpKSk7Cj4gKwo+ ICugoKCgoKCgoKCgoKCgoKBsZnNyID4+PSAxOwo+ICugoKCgoKCgoKCgoKCgoKBsZnNyID0gbGZz ciB8IChuZXdsZnNyMCA8PCAoc2l6ZSAtIDEpKTsKPiAroKCgoKCgoH0KPiAroKCgoKCgoHJldHVy biBsZnNyOwo+ICsKPiArfQoKSSBkb24ndCBoYXZlIHRoZSBzbGlnaHRlc3QgaWRlYSB3aGF0IHRo aXMgY29kZSBpcyBhYm91dCwgYnV0Cml0IGNlcnRhaW5seSBsb29rcyBpbmVmZmljaWVudCB0byBs b29wIDE2IG1pbGxpb24gdGltZXMgdG8KY29tcHV0ZSBhIGNvbnN0YW50LiBDb3VsZCB5b3UgdXNl IGEgZmFzdGVyIGFsZ29yaXRobSBpbnN0ZWFkLApvciBhdCBsZWFzdCBhZGQgYSBjb21tZW50IGFi b3V0IHdoeSB5b3UgZG8gaXQgdGhpcyB3YXk/Cgo+ICtzdGF0aWMgdm9pZCBjZWxsX2dsb2JhbF9z dG9wKHZvaWQpCj4gK3sKPiAroKCgoKCgoGlmIChzcHVfY3ljbGVfcmVzZXQpIHsKPiAroKCgoKCg oKCgoKCgoKCgY2VsbF9nbG9iYWxfc3RvcF9zcHUoKTsKPiAroKCgoKCgoH0gZWxzZSB7Cj4gK6Cg oKCgoKCgoKCgoKCgoGNlbGxfZ2xvYmFsX3N0b3BfcHB1KCk7Cj4gK6CgoKCgoKB9Cj4gKwo+ICt9 CgpUaGlzIGxvb2tzIHdlaXJkIGFzIHdlbGwuIEkgc3VwcG9zZSBpdCdzIGEgbGltaXRhdGlvbiBv ZiB0aGUgaGFyZHdhcmUKdGhhdCB5b3UgY2FuIG9ubHkgZG8gZWl0aGVyIHBwdSBvciBzcHUgcHJv ZmlsaW5nLiBIb3dldmVyLCBtYWtpbmcgdGhhdApkZXBlbmRlbnQgb2Ygd2hldGhlciB0aGUgJ3Nw dV9jeWNsZV9yZXNldCcgdmFyaWFibGUgaXMgc2V0IHNvdW5kcwpyYXRoZXIgYm9ndXMuCgpJIGRv bid0IGtub3cgd2hhdCB0aGUgYmVzdCBpbnRlcmZhY2UgZm9yIGNob29zaW5nIHRoZSB0YXJnZXQg ZnJvbQp1c2VyIHNwYWNlIHdvdWxkIGJlLCBidXQgeW91IHByb2JhYmx5IGFsc28gd2FudCB0byBi ZSBhYmxlIHRvCnN3aXRjaCBiZXR3ZWVuIHRoZW0gYXQgcnVuIHRpbWUuCgoJQXJuZCA8PjwK |
From: Arnd B. <ar...@ar...> - 2007-01-31 05:57:56
|
On Tuesday 30 January 2007 22:41, Maynard Johnson wrote: > Arnd Bergmann wrote: > >>+ kt = ktime_set(0, profiling_interval); > >>+ if (!spu_prof_running) > >>+ goto STOP; > >>+ hrtimer_forward(timer, timer->base->get_time(), kt); > >>+ return HRTIMER_RESTART; > > > > > > is hrtimer_forward really the right interface here? You are ignoring > > the number of overruns anyway, so hrtimer_start(,,) sounds more > > correct to me. > According to Tom Gleixner, "hrtimer_forward is a convenience function to > move the expiry time of a timer forward in multiples of the interval, so > it is in the future. After setting the expiry time you restart the > timer either with [sic] a return HRTIMER_RESTART (if you are in the > timer callback function)." > > Ok, I see. Have you seen the timer actually coming in late, resulting in hrtimer_forward returning non-zero? I guess it's not a big problem for statistic data collection if that happens, but you might still want to be able to see it. > >>+ /* Since cpufreq_quick_get returns frequency in kHz, we use > >>+ * USEC_PER_SEC here vs NSEC_PER_SEC. > >>+ */ > >>+ unsigned long nsPerCyc = (USEC_PER_SEC << SCALE_SHIFT)/khzfreq; > >>+ profiling_interval = (nsPerCyc * cycles_reset) >> SCALE_SHIFT; > >>+ > >>+ pr_debug("timer resolution: %lu\n", > >>+ TICK_NSEC); > > > > > > Don't you need to adapt the profiling_interval at run time, when cpufreq > > changes the core frequency? You should probably use > > cpufreq_register_notifier() to update this. > Since OProfile is a statistical profiler, the exact frequency is not > critical. The user is going to be looking for hot spots in their code, > so it's all relative. With that said, I don't imagine using the > cpufreq notiication would be a big deal. We'll look at it. > > >>@@ -480,7 +491,22 @@ > >> struct op_system_config *sys, int num_ctrs) > >> { > >> int i, j, cpu; > >>+ spu_cycle_reset = 0; > >> > >>+ /* The cpufreq_quick_get function requires that cbe_cpufreq module > >>+ * be loaded. This function is not actually provided and exported > >>+ * by cbe_cpufreq, but it relies on cbe_cpufreq initialize kernel > >>+ * data structures. Since there's no way for depmod to realize > >>+ * that our OProfile module depends on cbe_cpufreq, we currently > >>+ * are letting the userspace tool, opcontrol, ensure that the > >>+ * cbe_cpufreq module is loaded. > >>+ */ > >>+ khzfreq = cpufreq_quick_get(smp_processor_id()); > > > > > > You should probably have a fallback in here in case the cpufreq module > > is not loaded. There is a global variable ppc_proc_freq (in Hz) that > > you can access. > > Our userspace tool ensures the cpufreq module is loaded. You should not rely on user space tools to do the right thing in the kernel. Moreover, if the exact frequency is not that important, as you mentioned above, you can probably just hardcode a compile-time constant here. > >>+ * > >>+ * Ideally, we would like to be able to create the cached_info for > >>+ * an SPU task just one time -- when libspe first loads the SPU > >>+ * binary file. We would store the cached_info in a list. Then, as > >>+ * SPU tasks are switched out and new ones switched in, the cached_info > >>+ * for inactive tasks would be kept, and the active one would be placed > >>+ * at the head of the list. But this technique may not with > >>+ * current spufs functionality since the spu used in bind_context may > >>+ * be a different spu than was used in a previous bind_context for a > >>+ * reactivated SPU task. Additionally, a reactivated SPU task may be > >>+ * assigned to run on a different physical SPE. We will investigate > >>+ * further if this can be done. > >>+ * > >>+ */ > > > > > > You should stuff a pointer to cached_info into struct spu_context, > > e.g. 'void *profile_private'. > > > > > >>+struct cached_info { > >>+ vma_map_t * map; > >>+ struct spu * the_spu; > >>+ struct kref cache_ref; > >>+ struct list_head list; > >>+}; > > > > > > And replace the 'the_spu' member with a back pointer to the > > spu_context if you need it. > > > > > >>+ > >>+/* A data structure for cached information about active SPU tasks. > >>+ * Storage is dynamically allocated, sized as > >>+ * "number of active nodes multplied by 8". > >>+ * The info_list[n] member holds 0 or more > >>+ * 'struct cached_info' objects for SPU#=n. > >>+ * > >>+ * As currently implemented, there will only ever be one cached_info > >>+ * in the list for a given SPU. If we can devise a way to maintain > >>+ * multiple cached_infos in our list, then it would make sense > >>+ * to also cache the dcookie representing the PPU task application. > >>+ * See above description of struct cached_info for more details. > >>+ */ > >>+struct spu_info_stacks { > >>+ struct list_head * info_list; > >>+}; > > > > > > Why do you store pointers to list_head structures? If you want to store > > lists, you should have a lists_head itself in here. > info_list is an array of n lists, where n is the number of SPUs. My point was that it's not an array of lists, but an array of pointers to lists. The way that include/list.h works is by having a struct list_head as the anchor and then add nodes to it. By simply pointing to a list_head, you won't be able to use the list_for_each_entry() macro the way it is meant. > > > > I don't get it. What is the app_dcookie used for? If the spu binary is > > embedded into a library, you are still missing the dcookie to that .so file, > > because you return only an offset. > For embedded SPU app, the post-processing tool opens the PPE binary app > file and obtains the SPU ELF embedded thereine, and from that, we obtain > the name of the SPU binary. Also, the app name is included in the > report, along with the SPU binary filename, if the report contains > samples from more than one application. That's not what I meant. If you have an embedded spu ELF file in a shared library object, you end up recording the file of the main PPE binary, and the offset of the SPU ELF inside of the .so file, but not the name of the .so file itself. You also say that the you record the name of the application on purpose for separate SPU ELF files. My assumption was that this is not necessary, but I don't know much about that aspect of oprofile. My feeling is that the samples for an external SPU ELF file should be handled the same way that oprofile handles events in shared libraries on the PPU (e.g. in libc.so). Arnd <>< |
From: Maynard J. <may...@us...> - 2007-02-02 19:27:34
|
Arnd Bergmann wrote: > On Tuesday 30 January 2007 22:41, Maynard Johnson wrote: > >>Arnd Bergmann wrote: > > >>>>+ kt = ktime_set(0, profiling_interval); >>>>+ if (!spu_prof_running) >>>>+ goto STOP; >>>>+ hrtimer_forward(timer, timer->base->get_time(), kt); >>>>+ return HRTIMER_RESTART; >>> >>> >>>is hrtimer_forward really the right interface here? You are ignoring >>>the number of overruns anyway, so hrtimer_start(,,) sounds more >>>correct to me. >> >>According to Tom Gleixner, "hrtimer_forward is a convenience function to >>move the expiry time of a timer forward in multiples of the interval, so >>it is in the future. After setting the expiry time you restart the >>timer either with [sic] a return HRTIMER_RESTART (if you are in the >>timer callback function)." >> > > Ok, I see. Have you seen the timer actually coming in late, resulting > in hrtimer_forward returning non-zero? I guess it's not a big problem > for statistic data collection if that happens, but you might still want > to be able to see it. I don't think there's much point in knowing if we have overrun(s). We're not going to schedule the timer any differently. We want to keep the timer interrupts as consistent as possible according to the user's request. > > >>>>+ /* Since cpufreq_quick_get returns frequency in kHz, we use >>>>+ * USEC_PER_SEC here vs NSEC_PER_SEC. >>>>+ */ >>>>+ unsigned long nsPerCyc = (USEC_PER_SEC << SCALE_SHIFT)/khzfreq; >>>>+ profiling_interval = (nsPerCyc * cycles_reset) >> SCALE_SHIFT; >>>>+ >>>>+ pr_debug("timer resolution: %lu\n", >>>>+ TICK_NSEC); >>> >>> >>>Don't you need to adapt the profiling_interval at run time, when cpufreq >>>changes the core frequency? You should probably use >>>cpufreq_register_notifier() to update this. >> >>Since OProfile is a statistical profiler, the exact frequency is not >>critical. The user is going to be looking for hot spots in their code, >>so it's all relative. With that said, I don't imagine using the >>cpufreq notiication would be a big deal. We'll look at it. >> >> >>>>@@ -480,7 +491,22 @@ >>>> struct op_system_config *sys, int num_ctrs) >>>>{ >>>> int i, j, cpu; >>>>+ spu_cycle_reset = 0; >>>> >>>>+ /* The cpufreq_quick_get function requires that cbe_cpufreq module >>>>+ * be loaded. This function is not actually provided and exported >>>>+ * by cbe_cpufreq, but it relies on cbe_cpufreq initialize kernel >>>>+ * data structures. Since there's no way for depmod to realize >>>>+ * that our OProfile module depends on cbe_cpufreq, we currently >>>>+ * are letting the userspace tool, opcontrol, ensure that the >>>>+ * cbe_cpufreq module is loaded. >>>>+ */ >>>>+ khzfreq = cpufreq_quick_get(smp_processor_id()); >>> >>> >>>You should probably have a fallback in here in case the cpufreq module >>>is not loaded. There is a global variable ppc_proc_freq (in Hz) that >>>you can access. >> >>Our userspace tool ensures the cpufreq module is loaded. > > > You should not rely on user space tools to do the right thing in the kernel. Ok, we'll look at the fallback option you suggest. I don't recall if I even knew about ppc_proc_freq before or why I originally chose cpufreq_guick_get. Maybe we can do without the cpufreq and use ppc_proc_freq all the time. We'll see . . . > > Moreover, if the exact frequency is not that important, as you mentioned > above, you can probably just hardcode a compile-time constant here. Well, exact frequency isn't critical, but it should, as close as possible, correspond with the user's requested value for "spu cycle reset". > > >>>>+ * >>>>+ * Ideally, we would like to be able to create the cached_info for >>>>+ * an SPU task just one time -- when libspe first loads the SPU >>>>+ * binary file. We would store the cached_info in a list. Then, as >>>>+ * SPU tasks are switched out and new ones switched in, the cached_info >>>>+ * for inactive tasks would be kept, and the active one would be placed >>>>+ * at the head of the list. But this technique may not with >>>>+ * current spufs functionality since the spu used in bind_context may >>>>+ * be a different spu than was used in a previous bind_context for a >>>>+ * reactivated SPU task. Additionally, a reactivated SPU task may be >>>>+ * assigned to run on a different physical SPE. We will investigate >>>>+ * further if this can be done. >>>>+ * >>>>+ */ >>> >>> >>>You should stuff a pointer to cached_info into struct spu_context, >>>e.g. 'void *profile_private'. >>> >>> >>> >>>>+struct cached_info { >>>>+ vma_map_t * map; >>>>+ struct spu * the_spu; >>>>+ struct kref cache_ref; >>>>+ struct list_head list; >>>>+}; >>> >>> >>>And replace the 'the_spu' member with a back pointer to the >>>spu_context if you need it. >>> >>> >>> >>>>+ >>>>+/* A data structure for cached information about active SPU tasks. >>>>+ * Storage is dynamically allocated, sized as >>>>+ * "number of active nodes multplied by 8". >>>>+ * The info_list[n] member holds 0 or more >>>>+ * 'struct cached_info' objects for SPU#=n. >>>>+ * >>>>+ * As currently implemented, there will only ever be one cached_info >>>>+ * in the list for a given SPU. If we can devise a way to maintain >>>>+ * multiple cached_infos in our list, then it would make sense >>>>+ * to also cache the dcookie representing the PPU task application. >>>>+ * See above description of struct cached_info for more details. >>>>+ */ >>>>+struct spu_info_stacks { >>>>+ struct list_head * info_list; >>>>+}; >>> >>> >>>Why do you store pointers to list_head structures? If you want to store >>>lists, you should have a lists_head itself in here. >> >>info_list is an array of n lists, where n is the number of SPUs. > > > My point was that it's not an array of lists, but an array of pointers > to lists. The way that include/list.h works is by having a struct list_head > as the anchor and then add nodes to it. By simply pointing to a list_head, > you won't be able to use the list_for_each_entry() macro the way it is meant. I've got to rework this implementation anyway . . . > > [snip] -Maynard > > Arnd <>< |
From: Maynard J. <may...@us...> - 2007-02-03 23:50:47
|
Arnd Bergmann wrote: >On Monday 29 January 2007 20:48, Maynard Johnson wrote: > > >>Subject: Add support to OProfile for profiling Cell BE SPUs >> >> >> > > [snip] >>+ * >>+ * Ideally, we would like to be able to create the cached_info for >>+ * an SPU task just one time -- when libspe first loads the SPU >>+ * binary file. We would store the cached_info in a list. Then, as >>+ * SPU tasks are switched out and new ones switched in, the cached_info >>+ * for inactive tasks would be kept, and the active one would be placed >>+ * at the head of the list. But this technique may not with >>+ * current spufs functionality since the spu used in bind_context may >>+ * be a different spu than was used in a previous bind_context for a >>+ * reactivated SPU task. Additionally, a reactivated SPU task may be >>+ * assigned to run on a different physical SPE. We will investigate >>+ * further if this can be done. >>+ * >>+ */ >> >> > >You should stuff a pointer to cached_info into struct spu_context, >e.g. 'void *profile_private'. > > I seem to recall looking at this option a while back, but didn't go that route since struct spu_context is opaque to me. With such a teqnique, I could then use a simple 16-element array of pointers to cached_info objects, creating them as needed when spu_context->profile_private is NULL. I suppose the better option for now is to add a get_profile_private() function to SPUFs, rather than requiring spu_context to be visible. Don't know why I didn't think to do that before. Ah, well, live and learn. -Maynard > > >>+struct cached_info { >>+ vma_map_t * map; >>+ struct spu * the_spu; >>+ struct kref cache_ref; >>+ struct list_head list; >>+}; >> >> > >And replace the 'the_spu' member with a back pointer to the >spu_context if you need it. > > > > Arnd <>< > > |