summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2022-12-19 12:17:31 -0800
committerArnaldo Carvalho de Melo <acme@redhat.com>2022-12-21 14:52:39 -0300
commit5e3febe7b7b99f942311ddfa05bb06910d06b14d (patch)
tree58baf1524707635c5f58de9b601e34fc37049c73
parent511e19b9e2112463c33a744ecb8a798056074408 (diff)
downloadlinux-5e3febe7b7b99f942311ddfa05bb06910d06b14d.tar.gz
linux-5e3febe7b7b99f942311ddfa05bb06910d06b14d.tar.bz2
linux-5e3febe7b7b99f942311ddfa05bb06910d06b14d.zip
perf lock contention: Support lock addr/name filtering for BPF
Likewise, add addr_filter BPF hash map and check it with the lock address. $ sudo ./perf lock con -ab -L tasklist_lock -- ./perf bench sched messaging # Running 'sched/messaging' benchmark: # 20 sender and receiver processes per group # 10 groups == 400 processes run Total time: 0.169 [sec] contended total wait max wait avg wait type caller 18 174.09 us 25.31 us 9.67 us rwlock:W do_exit+0x36d 5 32.34 us 10.87 us 6.47 us rwlock:R do_wait+0x8b 4 15.41 us 4.73 us 3.85 us rwlock:W release_task+0x6e Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Blake Jones <blakejones@google.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Song Liu <song@kernel.org> Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20221219201732.460111-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/bpf_lock_contention.c42
-rw-r--r--tools/perf/util/bpf_skel/lock_contention.bpf.c17
2 files changed, 58 insertions, 1 deletions
diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c
index 58ac01b5a367..0236334fd69b 100644
--- a/tools/perf/util/bpf_lock_contention.c
+++ b/tools/perf/util/bpf_lock_contention.c
@@ -20,7 +20,7 @@ static struct lock_contention_bpf *skel;
int lock_contention_prepare(struct lock_contention *con)
{
int i, fd;
- int ncpus = 1, ntasks = 1, ntypes = 1;
+ int ncpus = 1, ntasks = 1, ntypes = 1, naddrs = 1;
struct evlist *evlist = con->evlist;
struct target *target = con->target;
@@ -49,9 +49,39 @@ int lock_contention_prepare(struct lock_contention *con)
if (con->filters->nr_types)
ntypes = con->filters->nr_types;
+ /* resolve lock name filters to addr */
+ if (con->filters->nr_syms) {
+ struct symbol *sym;
+ struct map *kmap;
+ unsigned long *addrs;
+
+ for (i = 0; i < con->filters->nr_syms; i++) {
+ sym = machine__find_kernel_symbol_by_name(con->machine,
+ con->filters->syms[i],
+ &kmap);
+ if (sym == NULL) {
+ pr_warning("ignore unknown symbol: %s\n",
+ con->filters->syms[i]);
+ continue;
+ }
+
+ addrs = realloc(con->filters->addrs,
+ (con->filters->nr_addrs + 1) * sizeof(*addrs));
+ if (addrs == NULL) {
+ pr_warning("memory allocation failure\n");
+ continue;
+ }
+
+ addrs[con->filters->nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
+ con->filters->addrs = addrs;
+ }
+ naddrs = con->filters->nr_addrs;
+ }
+
bpf_map__set_max_entries(skel->maps.cpu_filter, ncpus);
bpf_map__set_max_entries(skel->maps.task_filter, ntasks);
bpf_map__set_max_entries(skel->maps.type_filter, ntypes);
+ bpf_map__set_max_entries(skel->maps.addr_filter, naddrs);
if (lock_contention_bpf__load(skel) < 0) {
pr_err("Failed to load lock-contention BPF skeleton\n");
@@ -103,6 +133,16 @@ int lock_contention_prepare(struct lock_contention *con)
bpf_map_update_elem(fd, &con->filters->types[i], &val, BPF_ANY);
}
+ if (con->filters->nr_addrs) {
+ u8 val = 1;
+
+ skel->bss->has_addr = 1;
+ fd = bpf_map__fd(skel->maps.addr_filter);
+
+ for (i = 0; i < con->filters->nr_addrs; i++)
+ bpf_map_update_elem(fd, &con->filters->addrs[i], &val, BPF_ANY);
+ }
+
/* these don't work well if in the rodata section */
skel->bss->stack_skip = con->stack_skip;
skel->bss->aggr_mode = con->aggr_mode;
diff --git a/tools/perf/util/bpf_skel/lock_contention.bpf.c b/tools/perf/util/bpf_skel/lock_contention.bpf.c
index fb0128de7c00..ad0ca5d50557 100644
--- a/tools/perf/util/bpf_skel/lock_contention.bpf.c
+++ b/tools/perf/util/bpf_skel/lock_contention.bpf.c
@@ -69,11 +69,19 @@ struct {
__uint(max_entries, 1);
} type_filter SEC(".maps");
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(key_size, sizeof(__u64));
+ __uint(value_size, sizeof(__u8));
+ __uint(max_entries, 1);
+} addr_filter SEC(".maps");
+
/* control flags */
int enabled;
int has_cpu;
int has_task;
int has_type;
+int has_addr;
int stack_skip;
/* determine the key of lock stat */
@@ -111,6 +119,15 @@ static inline int can_record(u64 *ctx)
return 0;
}
+ if (has_addr) {
+ __u8 *ok;
+ __u64 addr = ctx[0];
+
+ ok = bpf_map_lookup_elem(&addr_filter, &addr);
+ if (!ok)
+ return 0;
+ }
+
return 1;
}
Y߿]F(7f5N'0%Yi'9<-jԣ)>&*Y 49$)^UڲvVȾ97SFuH5dhqq붒Mn􇝴XuZ!c_|{Ŭ^g eI~,"ƞz-u9F|9N/ njr-^+#tqݲ-}2P"3=bgAo[Ym?':NDx&Gg/VrISE9Bف <yt7^'ꤲ_ݾ"pZ }ψJ(3adSc4ڤF PARTň|zE~2B? fވVUSN}2s8SjOS2֤8mLr z,рvߠ!C-\.iL xFX=;orΥ3X=_~b9!xhJ(y^l|9|VHOG.tOj)5a_tFx'`A(k6QwooSt^$mTT٢e?t;gB^P9y#[WWy|kӾ2eU{D"5+mNCτ}GoUk[b0s :>-Ǩ۸4Q/eY:/i^O+XSoU>G|]aDXJ)5~ͤH-$;;I+LT{UQ}݄f| sϛR6i?qۍI/8c>RW4_Qb38k{;'}eSdA>=)Xث&a.+Y׳-q[0ik$#S}߯ 9˗N1y {<2տ?i""}Ή3-y׆QENjwl!$Ûխw5i}WBr?簵j{q-n}fU'5oMZURRW8qJHxdMuC,(=oAR÷<oӔ>GSbwIy>np5/:Wa cW.8?N7y//Ah-NMd,du}_קd߫++v~ˆii:@Mȣ2=`O],Q)KҐK>zMKlGE%}NJ[Jjݳ$:"@L H MhSFtv++"$V#p yLjB:V7Xۃ*wߦBgHB g=;#,? Q&a.il.cěnA]g}+Y Fbb@EB}&'>W"ۭo )UOO}dH7 ]O7 /m;c]񹍿JBĜѡ)t%6$,{|-Ӥp쭓 \\=7g l:ٔ.gpx9H/tHӳc$q8''3 xԿG0SF.s 4u2[%T,_1-=6SƖFgȼiaYtOfNV8RYuښcM[~Ŏ Mtd0oV7M]śx[D>Ēu*^G)kž4OdאXV3}˩V2XP;J7c=7& .SJ DxĿf;B\Ώ kQ/; Dːx P/[vn-ul1oĈ:0pb[pH3ۿ@ij!:?[ hf=nppyY$,2Ȳ,iUo'~^$5\p7V+L[x |=Reab.1~ЎaZ).ӼT)ͥy8K,3?rYY}K:ښU63V=Foe$XsNcκx 8:%0 $YZ? ]/Xb+ 1Œ b)ģ'D"O<=Y[f7|^0JNe>br:B$$ED|jӂIgQz&0^tF ¾pfIf/٬,x& ֋ {jx)U 07ً - mgx=m#.Rr dNώdc~LrR,g0u,4aM{_*g خ8پ6Ytx8ævg6X pigW/̥?(y FFz&6XjlpC9BQtH).ٶ,\5W^6זP$5h#Sf7?v@6[bsbE#||bՙV<(8 DY;GN/&`Vfje'f+GMtc߀Ϋչ &\LH+J2e%~л a{`?rdKG ]M:MFޖMhTPJwܹ'/Mk?Q"~/ e#H!^, >nxUefKݥf |2Kld by?QΒ" pxPgL͏SϱviZOo7< |1>YN K,xQZi̎3Jzxrw#/Ub@'je*4.]&8<*A[./|DRK)1gW)J '1;*jڜVӺjYESN2붞+NV1L[*55?KFOZVj:U*JOˁg?rak'ю q/Rz ȏQ4L?r?=\gFXi5&ע(XiZaSc#bZ3Vv[7+-Ωir[3OѲ5Ϝ8zV֦p1dbp9՘t<!WH0^:Y|ňGIiǭ KP/kђ>다?N:{}m|9ڿdEp(DD:0`IJM:{1?n\[. i3PJq8yk/: }J)Q07w8 p6i/U(]>Dn@nx0.C-Kbڛk9Ll5WƔv'U޴:z9~exTL/^o\aݽ&TB r״JS!kz녢"Ϯ^i84Ѥ'i\Qf(ޗRQFl ^:ysD77~M/U&c zYO'S!_}4(Y?!r>sh˚sG[ImݶZޏfm놞Y%ONϖĎ|+^-͉>])@&gd- G@ig3vU3(3TW.ݜzl|2V>V j|en H@L Cr)V^u,W*V*R ;7DeԱάuƹ w]:jSfJe6H'޹ceҩ$q +8ڞx͂ CVDB/pF=x,@fCrOVjxwLDeKrj4amԘ,a$ʺͫjW5ԫu6XIP rݣZ* ̦AZGc~bebubU͠zoYnUt&k7w| _] ӖZUթul7d/XTn#"z遆\N:p 2 dV*®\6\4ZS1#L?7d e::"8fb0Zx>즆Y]ZLMGI-wb[[wvPC.waM:ʵbv-ğJXo[׈g4JޔJ LU=hf.2=s(yRؙsBtTceԍIۉg92̔sxfO"naH(*yͣnQJ`e==ѬoZ$LVT2tl )~^~;&+h@uV7) E;ܿYqx)YRA<w2*O͉7KQQM[xmq%R2,ߝiH,8Y x7p%svܹ^j%""gv"liwg(5}`baUWzh Q`Ohe9vVp^ \wFLoYIÊu *_C>4X~@3G&푪%V!! ulV2@m|8b u - WY.<加ORJ1| [IclDŽմI٣9n)Uڋ뵣7鞛Y#W& WWa#þeg`_%YS63w362"%oc9A&s{30ngѣ˧{mdHa_8v0ФX$#Nx]]u,MZZdyrŪ@\EK~iZʒ`/0:]Kۓ_^kI(Qf[Td^7g]0!g—wM| <>=@&92ƒwuv:lt{hRQzȇ˝hj@oi\WF]_/o,`~{ 77/^^Z@]x'_= 'דnZZkFQާ\.;1ˋ@ ^ՃrKx-Ms֩x߀uղ@K|,|Ƞ%Njd˖Cz鸐#ejQKo`$ЯF x`]Ou^tYI`A6ZN;Ꮱú%FoC&Z/-bke2jHC#P(6&q~:.s e6ܒ܄O<~=Q6Ϫ fiԒ%%USts`tb+VP}r`%dt~AtV&.1fEXOb'+?e/>Ϗ" BZ_refBf-|vjEƬwQ䛅I|RV\dy`@ɇ2x!1"ǎh۬U~nJ7:j ֱAjLaK5G MU2H׶}<VT=z]5:T{v>4s8 Cn.׫XJCtɊ=zFG Wiߦ"@qFc]n7jo.nޱ+>&-Q҂hmRʣv<㌱}CGяCxp:yӓs^N{^ju2Tf@U{5"c-2&iCuPu[Һ"uxiCpk{ۧW/oZ2C4A@%lC[k,4I(rH幋enˈ|0u݃c 8$G푪X_z`-q[jH} <82a<нuΓ ~ w׼aFy}% f$D_>ҞI'Yhi5U%439+jk3衕%:ߖֺkZvR\̱4Tz=5F 1 :4TCj"dBYW.Fj]ɽc #-b2tNC6-ɭs&l5'{ok5}d#AGdjiq6IQZak5p] KxM&Uk:d'0{HG Z"Y9'V0Hǧ{ O=+lFo1D -r;So]g^s|WVp gĵiFiXXEHë &\V\5hDJI4T:"zd Դܣ4tD*@9u~D1قJ Mg,O^HGv1<-XX[[QgnoMxO"c>*Iwٸ.A4L4< ZW #b!IهU}TJvfzfĩzKM :ǟ//؅cZ* )r<=7L% GJ 50늒}P۞dG I(b0ID?US`EC`Am@#mL.M7L*ŃNz_H܁|p!}G&< ’Culf$@}I?TQDŽlNm25h^kRթl]RU] V9EfgUS 97$Xd^µR'gp< B+#2~^ 0{FfStgUc{&c| VB-Kq#TCB=TO{GnըK9.`-ޖ qK;`;R/#Ȇ@,p2nX֞зthlj(ޱrsV~깨 M?2ZZȾSw!sW s+b<SN+% \,tӇHPg+@! :JcB3??[FgV4h7&2F4X '*fvgԠUD#;9p4{7 #5/7*ͣ( d=5L+@hAv_*ЋeOLdMs%Z]&݆$ShʇƳ¢~@^Ϲ I@SU3Wݮwk$jCjzo2TqkkJߛh W(\5T<6 ^s|2ػ0JjJ (\ED^ԭʇDQ--û6)BQZ] 6y<+A&`d6^[R3Xl64h!IL*'yu3~}BadԵEou{ȋL_Q4ܙ'!H 3#-(}W.ptZLWvg Vot+iW_G ӂzdG$lc&D_ҎDC?}(qH7 "Qlh=?!o)iݖ8D ihh.zrj vW}0ˍj2N{-uŽp;@]=H݃3ǒvIc%9?4dfRw⹤9R#"iu I~E>Yo, \eWGh8vhnbzIь /30bӮx0* g`ӦsN^_~ZᱳKNLY07&:?9ICx4b%b ݟ.6jO]O<:x9)&@a$x7q)}r#zgdIL>o;66̘תm  W(\:^p6I:,BZÐ>1W˷pi$S|j8ʟ EbmH@^_M-k}^^|Z]5zWKjQ, ڱEek;~:;ݝTk 9M < `G|h M3ȵP':)0#QOƖ|Zv,S 3^+Z!v5ô2QX*؇|@ ɟRji$)ĂnK0PנeYSju?t8)tY<|ZIG]~̤Qqۇtn5ua"=FEN8GAj5F3k<r/){`ĽrI/*3lg.{Q䷼R]a$ZwSvI5H4>UA PHɛSvl]77ɌUeMf-$)wo% >fi\{FKHLBZ%}M'^* /QQ{NZLj> s-Y(xSX7 2B2u7SOĢ_ n|n슔CuMla_li9.P^/wQ}g[=ES{4JPC/t_uj{/ 48 VRV%b1uR\> 6p:]!W33 R@ux/%l2cוlwߦV{wMys5 K$9b<A:YnVS{+KϏ9^&M6:\UR{+hHXI؃"8KbEy$"7e%@ZXb3G)@H;l}MTWj1|3B,+w M|ا3zEVuT~\f_¦1 ~٫xS/Ҽ@ty!L]s#Op1kAOe ѝQҮ#9+15NrV%j0JZ"5!]d3^]*}:luE% %o[PfRW%Ӫp>c+@ O a^lVʃ<7).] m.JԚI+ 8iIIjN$f];Z遥$7?1Vo6  2}G^C+H$cqy1- @*- 7X1-! k!=f~Wş,.L(^ d_'hIjls0a$iCZ#m75 I`GFĥ&[w1h"U.v̉d˼anCZf]ه+B96bb- : <͈g1i|\8`~Q&j>? >ߗqr2. A1_JOJЇ,@)ޜlGߢ jF/綖ZS+4oJ"S@ct;V*e,,Y6YyjR!_z%аc1މӧUNxw`TAȼAgC4hH`SMnPp%fÖ\ȞzIj Up.#t1NjX6OsɊ^[( #,,㫁{,_(o۳c$ +0abɄw_)]Jݝ%II{PB|װV {&嗞>+}hKkr. pq\ ŵ Kl jlA;v߱k43h𚟫E*| u^Y޽v'?攰Si)3}㬁iA; 9PX3nwC5:-u,z tekUmzZ1`V{ه=7~A叮ܱMQ8cI_&M)!4]$9Łr/ϗxo96BRn[?fdpx_.2@CXH<՘q~,"$@X5/_{$yRҵɬY|.fs+ '*17k ۬flxDNiĊ TMHr;2돜/ޕg'{̄fe KbvTX]'DR;7? ^ h`/:n^x}6+zrI4 F X'iZRǁ0 yA sL@A80L4K-F`ٸP̌Y,[HDE+TV`œVtUNG#`닌"@"em 4E Zz6Sc=kZ2 ºR(ufKs6,ДEܭyWK@n>`ߧqs}UW9A3:8AꥒegGs|cR7!#Q^!-f ObƼDnOZlȪCD߀Ew,tՎz;ms_F)_|'~f2ZK7/5idQ.2vgA.Hon_M]HȘE#4ˑX0꥾^mt $ViERZkۏµ5pujykG6mZ#+:9`<j? |-v6t,'ZOCA #f}[3V@^6z2ӂ0ؐ9g/T1/U@fWdhA[<70Wk S8 _PN;ˍ.>N|Hy'+d0g.KQ.6mv%CT6yϐ& &kqrT?xo.lR 0Rh[y05`%GV_*g<}J <$I?S9^\QF,B cp> &@M64qZD/oԏe{cdr&<:3oLi #hi ћsTJ ( z)+=24Ϟ& eeF+.sdN”֑2*kk+q\މ ^VՂ eۙ+qpǑ}g41o>5 ^0dHȀk stX~[]BH1'vԕ(aYmnuÖsZ:]PT;T806ԤnCX*pjIƃ"D$y=x݄,ΧQ>&σp ;`ho~ $u{'̈́dߗLf-_yOL3IR~nm:OjYSГ6M5hN8e1P) SThO u;FO4.wI$c%v֠;&kpfj7)q_eHZ(T3H۠+&z"O XOoX&j'H.Zx80_nCᨚX[y]cl\֍?AFjpb5+?ʉL_utZbk$h&>6 1+N2ibwu$MG?7OH|RykamZ4M\ԴRfPV$]`zg? z;߯֗M0)s9S+RqLb(i85ߴ!!aY +Yr'<9ɴi̡ׄ`U tQQ؛@MZ T$H5>tf]02GH[V߸{*H5m0'*y+Gރ!n6n1i%U C(-wD|u^A; ˴FA\siH3ԂtW'wcLGF8T̗a~@O;&q.&Njl΄#Ps 9.Qjn Ԡim htyYɶ=݅MbO7_ً o擔& ̎V[{pCoݵ]TF^2G(6!=cɼwaP4 YJ`W0j!5mB2}A`]Q^PTYH,?LVdo ?& @ Wdcj{y8I6 +_nO ~|_9$l]`wAqo4q }NK;I/CBIpk9>'GU{˹#hDod3rio[^H$Bej lr9lغ1#iYD_+^!0̃o @p-ԓ37B gkfA2Vd&O zCK6*՜ ǿ+k`|1嗹F7Up4%CQq&-jkpZz=KW>x=r nJϕguM9qL9CTLbUmazxo^o)7w&Y1\a)K)'VxQ)5,e+t׾v٥!P r7K/|;R2"Xn$q+"KhqZ&OHC~XD&NQҘ%5Rz5$~swò>K5>HNkdCM-7CnO 1s,?m%}(xM ! Aޚl+3qMG)Ntȿ((S*botqmIgHLh}޹~h#6ֻZ3c9NZgOǃ[ u5ۛ׊ JkZQX/#%^Q,#Èb猡U8Vynʹ)XM p Z7͜{]? +iY%˛X_TQ+%Z뤠8 rDB, mmhsۏVf Uλ' X RL}7UN~թTfeS SEC{w + P~YtʌMv$5ƍ :Cw7:kвᾰsXgIjiF8 \Vz <ג17 6R7{]oQRfrfjqAA+W$g` 2- +ms '|8[ƕ<; /E.4%wϑ$4vŮ nݙo X#q?Ɠ7G9lSxXF*{T R876?ffW?M 7pVc=Fڝ$_8򣾝Q*IkfWKu:R]o$lkT %U})ةW;Mu=󛳿Q>`?]AӬR8V[{2”)s_}@:gDʖ$Hb-6 @`ɰ<$ptp9!J)=t,.9G/bX)sɀ&L;xUbK“6?7]EpZ'e ~6NNW~ؤ`cpu [*eP׶=[zTG %=6zt^J oxuս؜Ҁ NJ)ɸ^ީK=}Qy.k[}t^'^ù\=DF呐" \S abr;mdnƅ$ UH6\NCPv[vci]JOhT{\VK@k_fE$E +4"?@*\7#IԲRimżH˜.&<͡G}c w$E0b/W΃>Z[^pC5 Fhoݖ/XVv4>=Z$2нiZA",{Sv5vrʜH;۵Ɖ@ǯv7`1pF^vIZwz$k2oĚCL<!1 VC`;+?_-տNM\ ? -\gޅv]ۑ)&[<%[b;`B$z rZzl>bGOx-TMܝ#)n;$g %OW|I0k+;$cO\ep;`e4LrOn7|K$?7 .HR_͊:cE^p3&3G 4NhKrPglJV3$RV+vPfQz0:n8FE%}794c>hyl#TN,컁>WJH!kJ_.ƹKZ E1> MP}P9wZ4Tj Uu*׬BV[=ыw7T֨jzUƤ'jԪZA?Z8+.aqf^i-i'`t!yܔߥq\h5M֦gnF 8 =5Gv}Έ-˫(+mX+`Y,?ܘK  g HzڠE LփaʹՔ( 0YRv2kgkxuJ>2's>{2kCiypWdN.*bqT f@$Uvm#y?٤4\3W~ZtgQo7K9ze1Ө+d-}[szU=P^mBc! 82A9fxn2KZjt5 *&*0N=IWp,P0"^D78cunsga .? H/F̴Y>.ֈ.5Q;N%FY,jj⁴.W_c a6e_. eB F-=7 ։_%xIPv~S;7AgFAm4~׮IN)1¸H]I:[ab,d P EU\UW?@ e `Z5ۜ ޅ<-hָp E|UB^:ÅZ80Z~\1`y1BS9/>gmmr{/w^44NY"U? MC |vQ)BF 'zmmVujjQ=h\{š9ѓ;L ʪd<_ ?6GvWg0cUSLR&mrhNKcC.Z2D:Fr5,# Q; +WnKΧt==,yKԕt%/IH;F%0&u4ά@>N4Rf?{ۤȈ1:.{z[e~fLo*`aGWbFw9@iݳ(0]UWu|' j ^fNmdVUd}Ƀz0bP^> S[]%+RHQ*']VNH17Ŀ;ϙ"ܨcܽz0BZQ^-H? ^Ipf־x#Oý )uRS1A],c8NȰv喾SpﻻDzBtgPLLbBEQygʳ= ]:6qÜZHNPɰ$)~JpDځGwt2 YΥ{\8֫r*@_XL6m;-@-Ņ~4<9;)tbr%)+$w%ujRZdљj>5G؍DU4tI+ F`/tߑE7 S"\+c^L3roDBZOC)!ƖBOA.v::5@?V2{{wd.+s!,oJa{~×~yD" )7s6 @bi?$:'ϒX|'@.2ϱgu-MϕЌ/8u@d4D#GuO_B:\_Թj^9z5c'9Z!wҞd>65"]κd&d|Lץg\3O+ -;AԥG^ tix1lx؎ٟ&R;&` i%b!*@QwqU4. izuو>[DܝCoYiK{9nkɹgO27AC]Иfi(kdԣE:>G:X2i؝ު B @1fUeĪwIj7F7L$7_Ug49(K'Q=YR?c ;h"$Ţg:zm-_'?}jOA>jVCZHmd:UhjfdcW9]̌C}~qySReZQgV{hOݶߑHy'5$EQ~,\9 9}Rc1hFDMZjZCժOjМp:!2EvZ e\pɗ1zR_qm |ٱݳW&Oc@JJ4h7~H->z*ٓq~a-I42bh֟ds~pYqF{U}&#jC|ԥ*O*PQK7{ZYtwyG`N%QTcl/3˵),_ .bs1Ze>f-<PFTӪ5nH!SsS;xL>r^t sk'yΊ@3rGՋ:(|g~{XEmud؂ȴHR*){o$.?Q䥀m$t:oro𒍅AilxǍaMuڤswF4[FS5u \mSpB ً42h)"Q6ua. ?v_pQ&-  |ueV?ڂ<;&-RT(zl=O.)F{ Cψ W46\p82Ng~0 ۮqB"sC ;7 RJZHS{S4ڠC:u-F#(O +Z#Ɇ~yTɔ&Tڠu1Qᔖ-nխHtGjء+.9ϻL=d>H|nЦ`:Bۓc(.?l<1*plẍ́W0H9޵Q;! ԥ3ƂxI=l]&73 ~G[6"÷{jT~gq>u& Yԧfo3R huov B8\ :@i}1oK@d(#pF7[2oyRrAitydRTKb"]-06 #ۼfN01֙pQHB=lA.g~$w/d,QVOgu^:MRG;[Ւt[˴ 4S* 5pޏlrޣw\i7>ZEkuOO3G7Ae~;#_)Xʷ+pp%Up٬鞲REnhF [\uRڀk;Xgnj.݁"e)}HG0T}ē @{qw_[#Н>ӗd5 ꍽM`auL,KףpZtxuӬ- [!\[LMO=`{' cLՠH.rYy CT$w=Vjn>w9|֫:2 5U͸t'9kEh4S1VL+v 5_B&Yhړ dTK%V= <ᔃI}1rbI~0NҾ DaV8^67NW&Y;2C1;bs(\H}dm[ͷ$Ea&i8 >=|4A@{u\!׀JI)XY}" H51iJdFYg {RT)6`! lU[d ̕7r%x5`&{a2'{̳nX¿z/f/9DJ!_%Z}οM0}/25̮.F44Veѷ iäXc8M 3,a]pãwBS.vqᄤ@W æap;{3 owW /ə[8蓺48[5H a?K$ՏhacĹ"T̂QS }IORz8G"#ѬZ`BO+>jY+nL6?XA$@C?r` zz *riq˩i5ޓ۶xښTP/n{toή.6y8)h.j Hx~ /NH ʏt3Tkg8ꎻݖ"#SdVqMy1m*c& 8cVcЄtLn9бf#7?S'xG<ζڲsFt-^JW#_Ƀ/;b2.ީ˒wNZ4\[mwQ3 &Qߌ'[`Up=OگU5jx@qCwR>rc1B7Өx|I:8H4ys@ Pk{17ZU$0y]\&[%6 <兟|xȽ3qݐV Ō8wD}(v|00{$q-p̘XSV LўTC"}*?AA[D€tTV(Ӭ4ZWho@evƔ'Q3< lWVUWu apZ^1+s9;s^~R 0S렌hS5%'al,Ulܪ.\~tIWE瑆(&8 ;ljoEԇ8Of3-V]W0şUbzA XF"S`W'Y;N$cwݤP Qut;M3>d">C(`3}XSߚ( )@G4}guh~u ~{=k}zdQ_Zufn!!;lm/F6nd>Q@>g^'%SCHFeG\6 mbwkҲg=S sf^ fYE)I+)PFA 8닻 ,Od#{^v9v¤PusUp<8$w˝5.$"<45t9 ⃗lU5~Hy/{٣Ssbb4r~2kVФ1j)ɯ#.b֛v;/;KL7'A[Q@D򇗚W!]V K\$45mp>at$hc˳a֕zw0dpƐ۽9!Ӊ`_X #G &cW*kϦa?96|:FOV( k3-<+=.esqlZHj6^^ы}gڇhGcX[-׻ jT?umL)A'Bh\k9Sfr]]Qm:~p&+?-@Iuv_/iskEnw1ᙳ=UR)b6BF=2U49?tH x>BX,!P3{.B7cb|\g( KCMpۧ \frqRx"SX&O8P3ƣ )I١i՚R#'"]rO(|&T6$|iۡО6Q*s]ٗq@ z<%8ilN`e"nzX84(5E8yӊՅz@UTĖ-5SaBL3g,Fw{t&}v]V+P8/E!䜮>/^*jNZWlw {P6EMs%;#RHגzT+K9+Rt^;cQ? n/fs?1U?Π菔vk^(*ٴk^C(j)VW&L/D:g`> &zBb@_q?ɣ]\GBu1SfCZG&YnG"oY,S\ /GgI4򑥇 . 7 JIjB+VM4&.ah2`Wx<. Z?CH^̸~3?N iz bE%>}ao?2$so޵׿_M5L}QS&9'{ttZYE &_CWeEBIý. mo/DVȹXc&vYjË9" v4h_qK1Q_ +&lCȗdiؠ8a BzP<[5T؂gJ Mfo{6r]&)!I'A꘮$*gƅI hQ/+&4bũna (A AoU{ސ&IIP~ZZdpjjtEI0ccWX} %4/*nU 1[T򻤮ǥIz)퀿K-N=[p>Fo~Nf!#{˟]/4=i+ό%Q,tiMy EF%;W']g<Կ"YD渘h.kpbMtĞGK6vq &N~VWBg"ڸ|L w3t>h${p6Y}ԁ^Eos5CSq./4CVA )oP]CŠ~Mu,Q;C<;%\o'צ`JH+M ,.3R9Mo1g@Kl&:ZEʎyBMrSqʖd=mW_BJ`f|Ih&@֋m`Bk7\CFޑVXߒB"9tU&r<C?+i*+)!ߏ%gXn/%cd"{t4Us:d2UѸIî9UjuԨڮ0$mW(\"u8xO%25ޠŊu(Fq+K N$W'q8޺djpL:&+fl9ʴTe@O<.kK˝^ a5|>Liy%פ;[g?|75旴nDOZb!ʀ+@P fyXh]0ۙRº+5S9u}*t+qW.1BJ$_ؖZ^qύy-Wۤ=w;?}yh:@O4@hί'i)F?psGS(K5Òz=hѴ\kG袐2%VF5F]wO΍t^lDfCNq| H+F3|B:).".vS "йL3Qs>]YK"&;3:n8 MREE[8 gE0*% koP~PB$:}6AcXdiƀro2Y#H~OxP\fy%yxV=܂֖d+'%=>-6\WmU[yfL')砊N֌1#aF*`B\#Й257@;S7Mڐ. I GP֭$[ L͑xۿ:3ȯ4jVM:쀻b8"tZMZI6$}>5isUk{=rFlt9v>4 _ i%ߜk}>Ɉ$;M3uՂP5 X21鉝yڡA cE Ir G&4,oQkj3ʵYd=,BfN䓣  A~wĈ@*NyCكUe/tdkn.Wixdqwv Jr@V]SRкӢf@C%%P1j,XbBG-cn]|q”eP ύG9g<ƕ 781],+F!nrlXMN;-.:l#X1ʤkY`'wayFAT~4gW qMM(ZͭaRP?q'Oa'gKj0H0tՇZNCcc^%$71[ըiu*}P|Ӥ!5D.cHE$D*Y l}"B%mE a嶲oH4se•OhAhYUj ssaxd6Aa`+et1'n,16-Lٚ Nܮ6 4Um.5~"EX>]ϐ-s~:;f'3M'͍8@%WD%L~NR)oE\W {gQ)ZZVR9ڴ~RVvgfMSc7E;cCӤȭwh&?sw$>@H!Dj>d܄$=|TrpW(M9&9~7)BCRDr [%.]ѫFHB˒l!fӿOL-,=j{󧲣mϛ%w47 ٴb&VB PȀWy]b'GEi/"O.78 4#sϛ}`)ݓ!Yz1SJ>y'& " Z&BF+zGdI|`\ЪWgƢ=\|g c.["e*rEJo_ 2vm5ZU %Oj0N-=Qd{xV$&9M(iI'Ԛ^_ۓB 5 b==}w=؝I9 >t`ɎT%{+I̲ӗVn$ F {}Zu.@ĆPe SuV~}ZVXL^kı|[5;B D5~C}d>ԏh;$ z.^2[g,Ee,lYz0k.QWݵZ*V:q檜=4\3lX 6 'ڟ'=g#>/j̖&티\OaܸytEDڛ]17|VCsSBRx 76jcPRtuy4Ah:D1L^Qܝc3H8((¢g)[Y|A" 5CtjeȄGnZQtmKg&G :~ɀg{<^ȠM谪6 ;6 t^Um>}ZA>u1bO+V}{3({O> u*yZ)!ݝjv)V`6I~UP>Ԛ$<A< h:Ͽ)YI2 $ykй2^ꖀ8o#Q{|T:k |'m`XX~~[zΕkK-kثu-b_N@AzZ3XWio5Wʯvd349==[m'y.|%dW8?UY0,w_"bqwtq5_oƦjzZ pDvߛdFs@zF,Yuy>}k,l|1-zvG}OE8+g[1)punMjC3̛1R\Bqlu"?߻!ftq2/ AN|oXp5{_2'h>AOH{4]1JMrQ;~Gu|2tw } uϽq^Fv|jKp<}4H%\OQJ9b&uI]wrO A4I_Mg߿^O.j8y7+g XZj:GjS* ɶ:s_3'G(lC9YH^?TjڥQ7z\Hut]zlxD3Gkʙ9URп*t>ew"7aH4j3IJgJף)>i;&Ki"c媛GC7$]@o^h9bZMCR}|}>pm/;9>s4bGk4u:xnRр]EߕK;3%Cڸ>nA=T7U є̐juUg4\-\zFu>RkobO͘ع=y7dt;\$(CzYIL֋c'e lI_1UiR>D×|fNGFRBݍf&wpaP`yĚeagՉ 8;RN$Үǝnk A Fc]!0ڪJC0&=ZԸY&i"9W&0$<)NKR].5vL2X%Ru8za C۩5 $ f!0ǧvx+YxhmUFF6YVǙ;^UiTr/CcjӏEz0W=kwSU?ٞ#8FgF%æA2)5ӓ!Hޒ/i#kb_QI(c;V#Ur6#Հ*Q i%S>ji.k ƀT VYpLe9y+sbNՏσJ3G t M9$ nP^6x6mVV \JP Q's+#p>^d:L;M[u$-5vu ڙDx-O^B;Cscq~EZ L- BQtbK_g;"9QV*aٹ"Y' v6hEcG{y.sf%A5-4%i>83uAѧA2^m{ߵc|V/{G+x|+?$KcabYv !UѢAc :eYi5j/ ێ,`;NTsA[ќwr؝y!N. Ky!ՏK[ ;>(+*lyE- c_eI|^78ŧ:Oft7+́09|gae0&HyIopy~Ϫ8NԳ}x)pMHg8c䏌5t=9*|p:jV[L,ɷ*c RNZ> VgT ;=4'V?ڸFqލ/_ܠGE ˓yױon;TcQY+HtJ*=KHϓS5j!:5qDj"rV*b<377+jv3Z{`UN?w%\1$Gᤲ}>CFCsY">9)>ځbEݧE}O\?5y^#z)~PoHi(jK a9̀'a'NpOr OH> ¿Qyu08kh%CD43>5 ̞#.@\f*T+衁x%huREP-sn{)}ǡrpAthuATWŶ0C<|ϦJ~'};z4|2}٦x{"Cu44R(驺U> &7TYrrSZ "M55+Tm2,ޢ٧3sL˼wt$g~f9df~cVOBoJa2K༁j{yqN菨0缸K%Ri\ %f6u'KMwӒo[yIܺl͍ $5VFO>c&:{N\B@eK A=} U-2(|w=_TY,|^@uiKX 9C1n %m.sta8&UKU_.֎SrO GGd8I ^d N\Uz W%%6dI!f:f9 50 "1Jn0~]) J(#HoO2di{1Z屫\bKƑŹΒ10 P[{edpfTցRܺZ:[3'\_$Qߩ-*^h2GzW RrP)?JMsEj&7Ċ)2#-bڄH|~o iTbv>+ w嬣QMzg0~3/Mlf/? L0yؓBmdC;+HKN`ǗS&tjWu5FӼ |T:v+١N?W+N=f19):N Hyhܮhzs5O?l*8]\J< g-Yt39xx`ŔTݲ9' fB s/.:|zQyP0gGX% HPsw>h[9-ZS哤^W5MWgUM2ZbG"떡 M_dog%8W¾a ..v>(-#=X3B{Ju.U}L.ʩű,[q`]S$' `hbE^bêXdϡV x qQ3ګ-t2$Kol+ Hrn0f%!VFހ٬S:`T`=lLZja0!ӁC!ϳ4+Zף]=FUBZ%֋d< 3MW6H衎2lZ=sf2KBUJ XYJ$9;CZ')ӫւ sO{3b≧FNH-DB9A [ʟ0m6V]l⧂;p.yڭLjM(CN\KjU:U4j[/ .];ڌ﹒ ^m`Q/.Foje`s^SIũKi䷂)1QMݹ|pIΞzGrRr?4_Lw;]Ee >p:c<,V `3y4K {NIRM wT"&AxTt0lR#;Q|S |+%-#lIA'Hl A=XòIhsϫm58wu}>ja MQ9W.']?Tn?ghEq ,?*ȿφyPW0hzgbJ7%ן~X`B*x#AۘwT+% pWfi>s ~ 9-58r Qsp:P4=R&`"Ӏ MFnPn挹+dq(B`)%}7xx?fH"iuj%5/UUOuԖfec/hĴbK'@é<ώT \1ثetI={&k% IW6-8&UpзslW(،,u3F{u1}t$\dʉ0qҩuhbl@O&ώ>iLuӅ-K˯;|[uUAcTJS8汇)q/C,n0Nvl^jP?ib֑tB{?E>C}4&ѼR'uurKP@(@+-5z5H+5$ޞ-v v+ٯyFNWB.~`̫2mY+Eb/4p6ŐxC~:W 'Q ۋ58wٮ| 0^:Smd8.ImR! 8V: }&;v)?`]k($u$2DF 8Oc^Fj &f3nG[^ޔlI{@"ZWzBᒂ.ME{^ň\KJ#>m "'znW~+"ʔ|p;GڅjZ4}~>H0YFildK6[!mGc:_po$!=4rs/"iϾKr.FXpݕ޿w_(tԫ2IX k $T&iQnSM'.gj֮H:^ɋ|#2뤇 aEr8 I#t7"ix |G&65"!=6;,1͊3>Azar@H.ɕui_Lp+brڋEۏJhXȟ\Ԧ'n5xɼ-p|Q74\?6 $Y䖜/(gt2-KV%v擯ֹvc2~^,MT Ѝ!$aCg# Xd%Ơ*y ؋vrn;+r01XT 'y&}탵^K0(s Bfm+;M}$L-VwXbMjIF6_lwTu2OPDcd!LK>ԧ .b=s8}2)8T(!(k ƛ$߅?/pyǃL/"IP>OAoIj/[T#´qT ѫdPߕr!B;٩8$B,]?` Qgv eek@^К[k_^ZͷBݎ]ruuPMy m3zdrd).cEei$ VPo哏qvJ^g '\vw╽w˳Sjߕ%0K>fy,C\r>I,);)XHd6)\ *@ܛUJMScvD`tNU]ܩۀvMm6D'}Dwlӌ<` 6iUr}bWLRZj&P)p$4~eZbTܩw4unzTޫL:f3I FS t:cIv*&ɘ^f4Ilq)D-]NHw`xbJ_U:Wp8K fAxr8>籩{d֧~3gM0X tjB VM^Nʧ(U|%4z}SkVdz0~; ;5ED+krHlF3ˆaƞ,}8!)Ē)Og5axk;.Ыl"$blLY:^a), y]59)o-)Gw'V 4mjXl:" 눇Ѐy'oi5c @5CXK;lZ7w':|Ȍb2nU[J4jzmPSY[UŠ 0 &Qx竵ErN8']Va4-+K e6lp敷v̓gxq'eu)8=8igUZo> xLBdz )fOu@0ٟ),K|_49  !.™L||][GP> ]\1٫6{a}`0;ν7 'Zٱp*|~Rf6ƴ՚LC@4PӭV~kBKꭡ (\p ;ٕH%lTEހd %=vTܹ ;A^|EPGەm*p8Bb6h67y(xDl(fXTsmǽZaXIkZǏj:L;Z5-]|1kv.Dfy'_RV$sm\=( $J~6C>Eq朶R;{'|ik,W!?[}-B=e9ŏmp\,3~t`|_owҴBOWeI##Z~j]%KgUf#flź/xRcm`/>pAĺ96LIIQWd`dk:uh?S*t3PS}$8O&FŴz,|ms޿ni:6 MyMc[/=AE-(6^d "9S( nx@cQt@J> }1C_ø~Wl~r ` gd`ɢ9Ѭ .\:8!e[wé?x-vOֽ\Ɵ3'A,>7F昉;ОOfKBJVT^!ŇB6>! ;F =f_;x5q T¸Hkoz<,Hi$̷v4C:$k͎TR'Me[w_!CO"ԋVUR:ݨIJCeL55s>rjZa@߹{D/xht,{$ŎL;Zjd?}E*w8`U=nTytLd$KCߥvmZM1g*gj_l!\Zk2xdivNI :M56S5!}Bk 85 W(\rn_Wўh/4yI^Ջ(5Fr.?Oi% ᓦ`w#kv}qJw>UR8Kgۑ8J-QULzcM$F0^Β;hXtfFMV%Δ`YT2lAX5^>-KOl\7%jk{ crV /u-1E6mǢf%>ԇdѿ1UT8B26"9!}03z^zod͹s]޼*躤dhtIwwpH\n? xېNx16Zi<=N;(|+qs_oU~44<Ba]WKOE ({x,k.nDd֫KծuolY uzxcpJ n:/H |g`,P gd}Zg?6++ܓ7  T7,./>V?;>)a?F;j&d$+:/%% N!WOzȰ\P\mb:_vSuYyȞZc)g/fMh ѽwTd l>ޝ>ujokf5Ѣc[d(՘Yр{7G7;Ğ ԋ؄+#Dι8MQY]l pQO鼞wt~T~ wL L|E9 Nݪ2 $/W^_/5GԆ!ukC$eTm6\ҵ4(8qd9h={9EZURv7uDsPޘx- uW+]-ӎBcvhb{Cb#n8+dfNɩnjt2%COG3iɏJQv"$\Zp%+/PzAFS[g0GN+N5'* ء^CuSo&8sBdms%71ipR$C@HK@Hpc_L:$HHg=ȞD؃?p'$ήqdKېy~RMH jg//\0WKU]9kYgc Ƚԟ^RkFj˻tsev..IfzM!:u{d'aMx*O9l\W h >G^kmp\:tm\4'v lX6bb{+oʾQ ?LqN(h:::}2rIzHw9?$ ^- rfe:4puOP04Vֱ;wBDr3DURojnAhK]~n !;-7(% J,i,ܘ% rҨ]S>'+IUލ'^ n2$vx7lN>Q!}&rR[.3iRm׫@:ijv5UJu.!5 W(\ŠBY|;g228Eq?',Wo;BVWk@DћɎ[2sEE~lyjG} hO>Ig2$V|$b7 z\~رx#>s7jG.$ǎ>>D,sJH>M]d0q3onA nG79hVk̒Bv& v^ v@0Zv0ØP{N^rU ict&jD[[H3L &Sl@UG9ys C*!8}25ܧ؁}mGĖ䵽?P˅6hn{gr* }Z͔ɱ=(KWk"H̜ j>Q4sQ18qT.WDmZ~ܧ40}q1{?iiGJ<|VXO~լXMs~hqIΧ`[I'>@KN9*K