All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] Improve libaio IO priority support
@ 2021-07-06  0:17 Damien Le Moal
  2021-07-06  0:17 ` [PATCH 01/11] manpage: fix formatting Damien Le Moal
                   ` (11 more replies)
  0 siblings, 12 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

This series improves libaio engine support for IO priority, adding
options to allow for mixed priority workloads to be specified more
easily and to match the kernel supported IO priority features.

The first 3 patches are small cleanup and fixes in the manpage and
fiograph tool.

Patch 4 and 5 introduce some helper functions to simplify the code in
the followup patches.

Patch 6 changes the cmdprio_percentage option to allow specifying
different percentages for reads and writes.

Patch 7 and 8 introduce the aioprioclass, aioprio and aioprio_bssplit.
These together allow a script to specify different IO priorities for
reads and writes of different sizes with different percentages.

Patch 9 relaxes restrictions on the cmdprio_percentage option to allow
jobs to execute AIOs using a default priority as set with ioprio_set()
(as the kernel supports this).

Patch 10 introduces the log_prio option to log each IO priority value,
allowing users to do per-priority level performance analysis with
complex workloads using many jobs.

Finally, patch 11 adds a couple of example scripts to illustrate the use
of the new options introduced.

Comments are as always most welcome.

Damien Le Moal (11):
  manpage: fix formatting
  manpage: fix definition of prio and prioclass options
  tools: fiograph: do not overwrite input script file
  os: introduce ioprio_value() helper
  options: make parsing functions available to ioengines
  libaio,io_uring: improve cmdprio_percentage option
  libaio: introduce aioprio and aioprioclass options
  libaio: introduce aioprio_bssplit
  libaio: relax cdmprio_percentage constraints
  fio: Introduce the log_prio option
  examples: add libaio priority use examples

 HOWTO                            |  57 +++++++--
 backend.c                        |   1 +
 cconv.c                          |   2 +
 client.c                         |   2 +
 engines/filecreate.c             |   2 +-
 engines/filedelete.c             |   2 +-
 engines/filestat.c               |   2 +-
 engines/io_uring.c               |  33 +++--
 engines/libaio.c                 | 210 ++++++++++++++++++++++++++++---
 eta.c                            |   2 +-
 examples/aio-prio-bssplit.fio    |  17 +++
 examples/aio-prio-bssplit.png    | Bin 0 -> 48709 bytes
 examples/aio-prio-percentage.fio |  17 +++
 examples/aio-prio-percentage.png | Bin 0 -> 48752 bytes
 fio.1                            |  76 ++++++++---
 fio.h                            |   5 +
 init.c                           |   4 +
 io_u.c                           |  14 ++-
 io_u.h                           |  10 +-
 iolog.c                          |  45 +++++--
 iolog.h                          |  16 ++-
 options.c                        |  50 ++++----
 os/os-android.h                  |  24 ++--
 os/os-dragonfly.h                |   1 +
 os/os-linux.h                    |  24 ++--
 os/os.h                          |   4 +
 server.h                         |   3 +-
 stat.c                           |  75 +++++------
 stat.h                           |   9 +-
 thread_options.h                 |  20 +++
 tools/fiograph/fiograph.conf     |   4 +-
 tools/fiograph/fiograph.py       |   4 +-
 32 files changed, 574 insertions(+), 161 deletions(-)
 create mode 100644 examples/aio-prio-bssplit.fio
 create mode 100644 examples/aio-prio-bssplit.png
 create mode 100644 examples/aio-prio-percentage.fio
 create mode 100644 examples/aio-prio-percentage.png

-- 
2.31.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 01/11] manpage: fix formatting
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 02/11] manpage: fix definition of prio and prioclass options Damien Le Moal
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

For ioengine options supported by multiple ioengines, remove spaces
after commas in the ioengine list to have troff correctly format in bold
the entire ioengine list and option name. Also add "=int" indicators
missing for some options.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 fio.1 | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/fio.1 b/fio.1
index 5aa54a4d..1101a75d 100644
--- a/fio.1
+++ b/fio.1
@@ -1918,7 +1918,7 @@ In addition, there are some parameters which are only valid when a specific
 with the caveat that when used on the command line, they must come after the
 \fBioengine\fR that defines them is selected.
 .TP
-.BI (io_uring, libaio)cmdprio_percentage \fR=\fPint
+.BI (io_uring,libaio)cmdprio_percentage \fR=\fPint
 Set the percentage of I/O that will be issued with higher priority by setting
 the priority bit. Non-read I/O is likely unaffected by ``cmdprio_percentage``.
 This option cannot be used with the `prio` or `prioclass` options. For this
@@ -1999,20 +1999,20 @@ Detect when I/O threads are done, then exit.
 .BI (libhdfs)namenode \fR=\fPstr
 The hostname or IP address of a HDFS cluster namenode to contact.
 .TP
-.BI (libhdfs)port
+.BI (libhdfs)port \fR=\fPint
 The listening port of the HFDS cluster namenode.
 .TP
-.BI (netsplice,net)port
+.BI (netsplice,net)port \fR=\fPint
 The TCP or UDP port to bind to or connect to. If this is used with
 \fBnumjobs\fR to spawn multiple instances of the same job type, then
 this will be the starting port number since fio will use a range of
 ports.
 .TP
-.BI (rdma, librpma_*)port
+.BI (rdma,librpma_*)port \fR=\fPint
 The port to use for RDMA-CM communication. This should be the same
 value on the client and the server side.
 .TP
-.BI (netsplice,net, rdma)hostname \fR=\fPstr
+.BI (netsplice,net,rdma)hostname \fR=\fPstr
 The hostname or IP address to use for TCP, UDP or RDMA-CM based I/O.
 If the job is a TCP listener or UDP reader, the hostname is not used
 and must be omitted unless it is a valid UDP multicast address.
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 02/11] manpage: fix definition of prio and prioclass options
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
  2021-07-06  0:17 ` [PATCH 01/11] manpage: fix formatting Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 03/11] tools: fiograph: do not overwrite input script file Damien Le Moal
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

Remove the reference to the hipri_percentage option in the definition of
the prio and prioclass options as hipri_percentage controls the use of
RWF_HIPRI flag which triggers I/O completion polling, which is unrelated
with I/O priority (polling and I/O priority can be used together).

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 fio.1 | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fio.1 b/fio.1
index 1101a75d..d9a3593e 100644
--- a/fio.1
+++ b/fio.1
@@ -2624,13 +2624,11 @@ Set the I/O priority value of this job. Linux limits us to a positive value
 between 0 and 7, with 0 being the highest. See man
 \fBionice\fR\|(1). Refer to an appropriate manpage for other operating
 systems since meaning of priority may differ. For per-command priority
-setting, see I/O engine specific `cmdprio_percentage` and `hipri_percentage`
-options.
+setting, see the I/O engine specific `cmdprio_percentage` option.
 .TP
 .BI prioclass \fR=\fPint
 Set the I/O priority class. See man \fBionice\fR\|(1). For per-command
-priority setting, see I/O engine specific `cmdprio_percentage` and `hipri_percent`
-options.
+priority setting, see the I/O engine specific `cmdprio_percentage` option.
 .TP
 .BI cpus_allowed \fR=\fPstr
 Controls the same options as \fBcpumask\fR, but accepts a textual
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 03/11] tools: fiograph: do not overwrite input script file
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
  2021-07-06  0:17 ` [PATCH 01/11] manpage: fix formatting Damien Le Moal
  2021-07-06  0:17 ` [PATCH 02/11] manpage: fix definition of prio and prioclass options Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 04/11] os: introduce ioprio_value() helper Damien Le Moal
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

In fiograph.py, the setup_commandline() function mistakenly initializes
the output_file variable to the input fio script file, causing this file
to always be overwritten, even if an output file is specified using the
--output option. Fix this by properly initialzing the output_file
variable using the --output option argument value. If an output file
name is not provided, the input script file name is used by default.

Also fix fiograph configuration file to remove the cmdprio_percentage
option repeated entry for io_uring and libaio.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 tools/fiograph/fiograph.conf | 4 ++--
 tools/fiograph/fiograph.py   | 4 +++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/fiograph/fiograph.conf b/tools/fiograph/fiograph.conf
index 7b851e19..1d50d141 100644
--- a/tools/fiograph/fiograph.conf
+++ b/tools/fiograph/fiograph.conf
@@ -48,10 +48,10 @@ specific_options=https  http_host  http_user  http_pass  http_s3_key  http_s3_ke
 specific_options=ime_psync  ime_psyncv
 
 [ioengine_io_uring]
-specific_options=hipri  cmdprio_percentage  cmdprio_percentage  fixedbufs  registerfiles  sqthread_poll  sqthread_poll_cpu  nonvectored  uncached  nowait  force_async
+specific_options=hipri  cmdprio_percentage  fixedbufs  registerfiles  sqthread_poll  sqthread_poll_cpu  nonvectored  uncached  nowait  force_async
 
 [ioengine_libaio]
-specific_options=userspace_reap  cmdprio_percentage  cmdprio_percentage  nowait
+specific_options=userspace_reap  cmdprio_percentage  nowait
 
 [ioengine_libcufile]
 specific_options=gpu_dev_ids  cuda_io
diff --git a/tools/fiograph/fiograph.py b/tools/fiograph/fiograph.py
index 7695c964..b5669a2d 100755
--- a/tools/fiograph/fiograph.py
+++ b/tools/fiograph/fiograph.py
@@ -292,9 +292,11 @@ def setup_commandline():
 def main():
     global config_file
     args = setup_commandline()
-    output_file = args.file
     if args.output is None:
+        output_file = args.file
         output_file = output_file.replace('.fio', '')
+    else:
+        output_file = args.output
     config_file = configparser.RawConfigParser(allow_no_value=True)
     config_file.read(args.config)
     fio_to_graphviz(args.file, args.format).render(output_file, view=args.view)
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 04/11] os: introduce ioprio_value() helper
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
                   ` (2 preceding siblings ...)
  2021-07-06  0:17 ` [PATCH 03/11] tools: fiograph: do not overwrite input script file Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 05/11] options: make parsing functions available to ioengines Damien Le Moal
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

Introduce the ioprio_value() helper function to calculate a priority
value based on a priority class and priority level. For Linux and
Android, this is defined as an integer equal to the priority class
shifted left by 13 bits and or-ed with the priority level. For
Dragonfly, ioprio_value() simply return the priority level as their is
no concept of priority class.

Use this new helper in the io_uring and libaio engines to set IO
priority when the cmdprio_percentage option is used.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 engines/io_uring.c |  2 +-
 engines/libaio.c   |  2 +-
 os/os-android.h    | 19 ++++++++++++-------
 os/os-dragonfly.h  |  1 +
 os/os-linux.h      | 19 ++++++++++++-------
 os/os.h            |  1 +
 6 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/engines/io_uring.c b/engines/io_uring.c
index 9c091e37..1ab1406f 100644
--- a/engines/io_uring.c
+++ b/engines/io_uring.c
@@ -381,7 +381,7 @@ static void fio_ioring_prio_prep(struct thread_data *td, struct io_u *io_u)
 	struct ioring_options *o = td->eo;
 	struct ioring_data *ld = td->io_ops_data;
 	if (rand_between(&td->prio_state, 0, 99) < o->cmdprio_percentage) {
-		ld->sqes[io_u->index].ioprio = IOPRIO_CLASS_RT << IOPRIO_CLASS_SHIFT;
+		ld->sqes[io_u->index].ioprio = ioprio_value(IOPRIO_CLASS_RT, 0);
 		io_u->flags |= IO_U_F_PRIORITY;
 	}
 	return;
diff --git a/engines/libaio.c b/engines/libaio.c
index b909b79e..b12b6ffc 100644
--- a/engines/libaio.c
+++ b/engines/libaio.c
@@ -136,7 +136,7 @@ static void fio_libaio_prio_prep(struct thread_data *td, struct io_u *io_u)
 {
 	struct libaio_options *o = td->eo;
 	if (rand_between(&td->prio_state, 0, 99) < o->cmdprio_percentage) {
-		io_u->iocb.aio_reqprio = IOPRIO_CLASS_RT << IOPRIO_CLASS_SHIFT;
+		io_u->iocb.aio_reqprio = ioprio_value(IOPRIO_CLASS_RT, 0);
 		io_u->iocb.u.c.flags |= IOCB_FLAG_IOPRIO;
 		io_u->flags |= IO_U_F_PRIORITY;
 	}
diff --git a/os/os-android.h b/os/os-android.h
index a81cd815..6801b8a8 100644
--- a/os/os-android.h
+++ b/os/os-android.h
@@ -173,16 +173,21 @@ enum {
 #define IOPRIO_MIN_PRIO_CLASS	0
 #define IOPRIO_MAX_PRIO_CLASS	3
 
-static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio)
+static inline int ioprio_value(int ioprio_class, int ioprio)
 {
 	/*
-	 * If no class is set, assume BE
-	 */
-	if (!ioprio_class)
-		ioprio_class = IOPRIO_CLASS_BE;
+         * If no class is set, assume BE
+         */
+        if (!ioprio_class)
+                ioprio_class = IOPRIO_CLASS_BE;
+
+	return (ioprio_class << IOPRIO_CLASS_SHIFT) | ioprio;
+}
 
-	ioprio |= ioprio_class << IOPRIO_CLASS_SHIFT;
-	return syscall(__NR_ioprio_set, which, who, ioprio);
+static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio)
+{
+	return syscall(__NR_ioprio_set, which, who,
+		       ioprio_value(ioprio_class, ioprio));
 }
 
 #ifndef BLKGETSIZE64
diff --git a/os/os-dragonfly.h b/os/os-dragonfly.h
index 6e465894..5b37a37e 100644
--- a/os/os-dragonfly.h
+++ b/os/os-dragonfly.h
@@ -171,6 +171,7 @@ static inline int fio_getaffinity(int pid, os_cpu_mask_t *mask)
  * ioprio_set() with 4 arguments, so define fio's ioprio_set() as a macro.
  * Note that there is no idea of class within ioprio_set(2) unlike Linux.
  */
+#define ioprio_value(ioprio_class, ioprio)	(ioprio)
 #define ioprio_set(which, who, ioprio_class, ioprio)	\
 	ioprio_set(which, who, ioprio)
 
diff --git a/os/os-linux.h b/os/os-linux.h
index f7137abe..87bed43b 100644
--- a/os/os-linux.h
+++ b/os/os-linux.h
@@ -120,16 +120,21 @@ enum {
 #define IOPRIO_MIN_PRIO_CLASS	0
 #define IOPRIO_MAX_PRIO_CLASS	3
 
-static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio)
+static inline int ioprio_value(int ioprio_class, int ioprio)
 {
 	/*
-	 * If no class is set, assume BE
-	 */
-	if (!ioprio_class)
-		ioprio_class = IOPRIO_CLASS_BE;
+         * If no class is set, assume BE
+         */
+        if (!ioprio_class)
+                ioprio_class = IOPRIO_CLASS_BE;
+
+	return (ioprio_class << IOPRIO_CLASS_SHIFT) | ioprio;
+}
 
-	ioprio |= ioprio_class << IOPRIO_CLASS_SHIFT;
-	return syscall(__NR_ioprio_set, which, who, ioprio);
+static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio)
+{
+	return syscall(__NR_ioprio_set, which, who,
+		       ioprio_value(ioprio_class, ioprio));
 }
 
 #ifndef CONFIG_HAVE_GETTID
diff --git a/os/os.h b/os/os.h
index e47d3d97..7bf7c53c 100644
--- a/os/os.h
+++ b/os/os.h
@@ -118,6 +118,7 @@ extern int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu);
 #endif
 
 #ifndef FIO_HAVE_IOPRIO
+#define ioprio_value(prioclass, prio)	(0)
 #define ioprio_set(which, who, prioclass, prio)	(0)
 #endif
 
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 05/11] options: make parsing functions available to ioengines
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
                   ` (3 preceding siblings ...)
  2021-07-06  0:17 ` [PATCH 04/11] os: introduce ioprio_value() helper Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 06/11] libaio,io_uring: improve cmdprio_percentage option Damien Le Moal
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

Move the declaration of split_parse_ddir(), str_split_parse() and
of the split_parse_fn typedef to thread_options.h so that
IO engines can use these functions to parse options. The definition of
struct split is also moved to thread_options.h from options.c.

The type of the split_parse_fn callback function is changed to add a
void * argument that can be used for an option parsing callback to pass
a private data pointer to the split_parse_fn function. This can be used
by an IO engine to pass a pointer to its engine specific option
structure as td->eo is not yet set when options are being parsed.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 options.c        | 40 ++++++++++++++++------------------------
 thread_options.h | 16 ++++++++++++++++
 2 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/options.c b/options.c
index a8986d11..50e48815 100644
--- a/options.c
+++ b/options.c
@@ -73,13 +73,7 @@ static int bs_cmp(const void *p1, const void *p2)
 	return (int) bsp1->perc - (int) bsp2->perc;
 }
 
-struct split {
-	unsigned int nr;
-	unsigned long long val1[ZONESPLIT_MAX];
-	unsigned long long val2[ZONESPLIT_MAX];
-};
-
-static int split_parse_ddir(struct thread_options *o, struct split *split,
+int split_parse_ddir(struct thread_options *o, struct split *split,
 			    char *str, bool absolute, unsigned int max_splits)
 {
 	unsigned long long perc;
@@ -138,8 +132,8 @@ static int split_parse_ddir(struct thread_options *o, struct split *split,
 	return 0;
 }
 
-static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str,
-			bool data)
+static int bssplit_ddir(struct thread_options *o, void *eo,
+			enum fio_ddir ddir, char *str, bool data)
 {
 	unsigned int i, perc, perc_missing;
 	unsigned long long max_bs, min_bs;
@@ -211,10 +205,8 @@ static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str,
 	return 0;
 }
 
-typedef int (split_parse_fn)(struct thread_options *, enum fio_ddir, char *, bool);
-
-static int str_split_parse(struct thread_data *td, char *str,
-			   split_parse_fn *fn, bool data)
+int str_split_parse(struct thread_data *td, char *str,
+		    split_parse_fn *fn, void *eo, bool data)
 {
 	char *odir, *ddir;
 	int ret = 0;
@@ -223,37 +215,37 @@ static int str_split_parse(struct thread_data *td, char *str,
 	if (odir) {
 		ddir = strchr(odir + 1, ',');
 		if (ddir) {
-			ret = fn(&td->o, DDIR_TRIM, ddir + 1, data);
+			ret = fn(&td->o, eo, DDIR_TRIM, ddir + 1, data);
 			if (!ret)
 				*ddir = '\0';
 		} else {
 			char *op;
 
 			op = strdup(odir + 1);
-			ret = fn(&td->o, DDIR_TRIM, op, data);
+			ret = fn(&td->o, eo, DDIR_TRIM, op, data);
 
 			free(op);
 		}
 		if (!ret)
-			ret = fn(&td->o, DDIR_WRITE, odir + 1, data);
+			ret = fn(&td->o, eo, DDIR_WRITE, odir + 1, data);
 		if (!ret) {
 			*odir = '\0';
-			ret = fn(&td->o, DDIR_READ, str, data);
+			ret = fn(&td->o, eo, DDIR_READ, str, data);
 		}
 	} else {
 		char *op;
 
 		op = strdup(str);
-		ret = fn(&td->o, DDIR_WRITE, op, data);
+		ret = fn(&td->o, eo, DDIR_WRITE, op, data);
 		free(op);
 
 		if (!ret) {
 			op = strdup(str);
-			ret = fn(&td->o, DDIR_TRIM, op, data);
+			ret = fn(&td->o, eo, DDIR_TRIM, op, data);
 			free(op);
 		}
 		if (!ret)
-			ret = fn(&td->o, DDIR_READ, str, data);
+			ret = fn(&td->o, eo, DDIR_READ, str, data);
 	}
 
 	return ret;
@@ -270,7 +262,7 @@ static int str_bssplit_cb(void *data, const char *input)
 	strip_blank_front(&str);
 	strip_blank_end(str);
 
-	ret = str_split_parse(td, str, bssplit_ddir, false);
+	ret = str_split_parse(td, str, bssplit_ddir, NULL, false);
 
 	if (parse_dryrun()) {
 		int i;
@@ -906,8 +898,8 @@ static int str_sfr_cb(void *data, const char *str)
 }
 #endif
 
-static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir,
-			   char *str, bool absolute)
+static int zone_split_ddir(struct thread_options *o, void *eo,
+			   enum fio_ddir ddir, char *str, bool absolute)
 {
 	unsigned int i, perc, perc_missing, sperc, sperc_missing;
 	struct split split;
@@ -1012,7 +1004,7 @@ static int parse_zoned_distribution(struct thread_data *td, const char *input,
 	}
 	str += strlen(pre);
 
-	ret = str_split_parse(td, str, zone_split_ddir, absolute);
+	ret = str_split_parse(td, str, zone_split_ddir, NULL, absolute);
 
 	free(p);
 
diff --git a/thread_options.h b/thread_options.h
index 05c2d138..23c4f28c 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -9,6 +9,7 @@
 #include "lib/ieee754.h"
 #include "lib/pattern.h"
 #include "td_error.h"
+#include "flist.h"
 
 enum fio_zone_mode {
 	ZONE_MODE_NOT_SPECIFIED	= 0,
@@ -36,6 +37,12 @@ enum fio_memtype {
 #define BSSPLIT_MAX	64
 #define ZONESPLIT_MAX	256
 
+struct split {
+	unsigned int nr;
+	unsigned long long val1[ZONESPLIT_MAX];
+	unsigned long long val2[ZONESPLIT_MAX];
+};
+
 struct bssplit {
 	uint64_t bs;
 	uint32_t perc;
@@ -666,4 +673,13 @@ extern void convert_thread_options_to_net(struct thread_options_pack *top, struc
 extern int fio_test_cconv(struct thread_options *);
 extern void options_default_fill(struct thread_options *o);
 
+typedef int (split_parse_fn)(struct thread_options *, void *,
+			     enum fio_ddir, char *, bool);
+
+extern int str_split_parse(struct thread_data *td, char *str,
+			   split_parse_fn *fn, void *eo, bool data);
+
+extern int split_parse_ddir(struct thread_options *o, struct split *split,
+			    char *str, bool absolute, unsigned int max_splits);
+
 #endif
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 06/11] libaio,io_uring: improve cmdprio_percentage option
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
                   ` (4 preceding siblings ...)
  2021-07-06  0:17 ` [PATCH 05/11] options: make parsing functions available to ioengines Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 07/11] libaio: introduce aioprio and aioprioclass options Damien Le Moal
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

The cmdprio_percentage option of the libaio and io_uring engines defines
a single percentage that applies to all IO operations, regardless of
their direction. This prevents defining different high priority IO
percentages for reads and writes operations. This differentiation can
however be useful in the case of a mixed read-write workload (rwmixread
and rwmixwrite options).

Change the option definition to allow specifying a comma separated list
of percentages, 2 at most, one for read and one for writes. If only a
single percentage is defined, it applies to both reads and writes as
before. The cmdprio_percentage option becomes an array of DDIR_RWDIR_CNT
elements indexed with enum fio_ddir values. The last entry of the array
(for DDIR_TRIM) is always 0.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 HOWTO              | 16 ++++++++--------
 engines/io_uring.c | 27 +++++++++++++++++----------
 engines/libaio.c   | 26 +++++++++++++++++---------
 fio.1              | 14 +++++++-------
 4 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/HOWTO b/HOWTO
index 86fb2964..36ad8176 100644
--- a/HOWTO
+++ b/HOWTO
@@ -2117,14 +2117,14 @@ In addition, there are some parameters which are only valid when a specific
 with the caveat that when used on the command line, they must come after the
 :option:`ioengine` that defines them is selected.
 
-.. option:: cmdprio_percentage=int : [io_uring] [libaio]
-
-    Set the percentage of I/O that will be issued with higher priority by setting
-    the priority bit. Non-read I/O is likely unaffected by ``cmdprio_percentage``.
-    This option cannot be used with the `prio` or `prioclass` options. For this
-    option to set the priority bit properly, NCQ priority must be supported and
-    enabled and :option:`direct`\=1 option must be used. fio must also be run as
-    the root user.
+.. option:: cmdprio_percentage=int[,int] : [io_uring] [libaio]
+
+    Set the percentage of I/O that will be issued with the highest priority.
+    Default: 0. A single value applies to reads and writes. Comma-separated
+    values may be specified for reads and writes. This option cannot be used
+    with the :option:`prio` or :option:`prioclass` options. For this option
+    to be effective, NCQ priority must be supported and enabled, and `direct=1'
+    option must be used. fio must also be run as the root user.
 
 .. option:: fixedbufs : [io_uring]
 
diff --git a/engines/io_uring.c b/engines/io_uring.c
index 1ab1406f..d083a65f 100644
--- a/engines/io_uring.c
+++ b/engines/io_uring.c
@@ -74,7 +74,7 @@ struct ioring_data {
 struct ioring_options {
 	void *pad;
 	unsigned int hipri;
-	unsigned int cmdprio_percentage;
+	unsigned int cmdprio_percentage[DDIR_RWDIR_CNT];
 	unsigned int fixedbufs;
 	unsigned int registerfiles;
 	unsigned int sqpoll_thread;
@@ -120,8 +120,9 @@ static struct fio_option options[] = {
 		.name	= "cmdprio_percentage",
 		.lname	= "high priority percentage",
 		.type	= FIO_OPT_INT,
-		.off1	= offsetof(struct ioring_options, cmdprio_percentage),
-		.minval	= 1,
+		.off1	= offsetof(struct ioring_options, cmdprio_percentage[DDIR_READ]),
+		.off2	= offsetof(struct ioring_options, cmdprio_percentage[DDIR_WRITE]),
+		.minval	= 0,
 		.maxval	= 100,
 		.help	= "Send high priority I/O this percentage of the time",
 		.category = FIO_OPT_C_ENGINE,
@@ -380,11 +381,12 @@ static void fio_ioring_prio_prep(struct thread_data *td, struct io_u *io_u)
 {
 	struct ioring_options *o = td->eo;
 	struct ioring_data *ld = td->io_ops_data;
-	if (rand_between(&td->prio_state, 0, 99) < o->cmdprio_percentage) {
+	unsigned int p = o->cmdprio_percentage[io_u->ddir];
+
+	if (p && rand_between(&td->prio_state, 0, 99) < p) {
 		ld->sqes[io_u->index].ioprio = ioprio_value(IOPRIO_CLASS_RT, 0);
 		io_u->flags |= IO_U_F_PRIORITY;
 	}
-	return;
 }
 
 static enum fio_q_status fio_ioring_queue(struct thread_data *td,
@@ -415,7 +417,7 @@ static enum fio_q_status fio_ioring_queue(struct thread_data *td,
 	if (next_tail == atomic_load_acquire(ring->head))
 		return FIO_Q_BUSY;
 
-	if (o->cmdprio_percentage)
+	if (o->cmdprio_percentage[io_u->ddir])
 		fio_ioring_prio_prep(td, io_u);
 	ring->array[tail & ld->sq_ring_mask] = io_u->index;
 	atomic_store_release(ring->tail, next_tail);
@@ -727,6 +729,7 @@ static int fio_ioring_init(struct thread_data *td)
 	struct ioring_options *o = td->eo;
 	struct ioring_data *ld;
 	struct thread_options *to = &td->o;
+	int p;
 
 	/* sqthread submission requires registered files */
 	if (o->sqpoll_thread)
@@ -753,11 +756,15 @@ static int fio_ioring_init(struct thread_data *td)
 	/*
 	 * Check for option conflicts
 	 */
-	if ((fio_option_is_set(to, ioprio) || fio_option_is_set(to, ioprio_class)) &&
-			o->cmdprio_percentage != 0) {
+	p = o->cmdprio_percentage[DDIR_READ] +
+		o->cmdprio_percentage[DDIR_WRITE];
+	if (p &&
+	    (fio_option_is_set(to, ioprio) ||
+	     fio_option_is_set(to, ioprio_class))) {
 		log_err("%s: cmdprio_percentage option and mutually exclusive "
-				"prio or prioclass option is set, exiting\n", to->name);
-		td_verror(td, EINVAL, "fio_io_uring_init");
+			"prio or prioclass option is set, exiting\n",
+			to->name);
+		td_verror(td, EINVAL, "fio_ioring_init");
 		return 1;
 	}
 
diff --git a/engines/libaio.c b/engines/libaio.c
index b12b6ffc..1e997cce 100644
--- a/engines/libaio.c
+++ b/engines/libaio.c
@@ -55,7 +55,7 @@ struct libaio_data {
 struct libaio_options {
 	void *pad;
 	unsigned int userspace_reap;
-	unsigned int cmdprio_percentage;
+	unsigned int cmdprio_percentage[DDIR_RWDIR_CNT];
 	unsigned int nowait;
 };
 
@@ -74,8 +74,9 @@ static struct fio_option options[] = {
 		.name	= "cmdprio_percentage",
 		.lname	= "high priority percentage",
 		.type	= FIO_OPT_INT,
-		.off1	= offsetof(struct libaio_options, cmdprio_percentage),
-		.minval	= 1,
+		.off1	= offsetof(struct libaio_options, cmdprio_percentage[DDIR_READ]),
+		.off2	= offsetof(struct libaio_options, cmdprio_percentage[DDIR_WRITE]),
+		.minval	= 0,
 		.maxval	= 100,
 		.help	= "Send high priority I/O this percentage of the time",
 		.category = FIO_OPT_C_ENGINE,
@@ -135,12 +136,13 @@ static int fio_libaio_prep(struct thread_data *td, struct io_u *io_u)
 static void fio_libaio_prio_prep(struct thread_data *td, struct io_u *io_u)
 {
 	struct libaio_options *o = td->eo;
-	if (rand_between(&td->prio_state, 0, 99) < o->cmdprio_percentage) {
+	unsigned int p = o->cmdprio_percentage[io_u->ddir];
+
+	if (p && rand_between(&td->prio_state, 0, 99) < p) {
 		io_u->iocb.aio_reqprio = ioprio_value(IOPRIO_CLASS_RT, 0);
 		io_u->iocb.u.c.flags |= IOCB_FLAG_IOPRIO;
 		io_u->flags |= IO_U_F_PRIORITY;
 	}
-	return;
 }
 
 static struct io_u *fio_libaio_event(struct thread_data *td, int event)
@@ -277,7 +279,7 @@ static enum fio_q_status fio_libaio_queue(struct thread_data *td,
 		return FIO_Q_COMPLETED;
 	}
 
-	if (o->cmdprio_percentage)
+	if (o->cmdprio_percentage[io_u->ddir])
 		fio_libaio_prio_prep(td, io_u);
 
 	ld->iocbs[ld->head] = &io_u->iocb;
@@ -422,6 +424,7 @@ static int fio_libaio_init(struct thread_data *td)
 	struct libaio_data *ld;
 	struct thread_options *to = &td->o;
 	struct libaio_options *o = td->eo;
+	int p;
 
 	ld = calloc(1, sizeof(*ld));
 
@@ -432,13 +435,18 @@ static int fio_libaio_init(struct thread_data *td)
 	ld->io_us = calloc(ld->entries, sizeof(struct io_u *));
 
 	td->io_ops_data = ld;
+
 	/*
 	 * Check for option conflicts
 	 */
-	if ((fio_option_is_set(to, ioprio) || fio_option_is_set(to, ioprio_class)) &&
-			o->cmdprio_percentage != 0) {
+	p = o->cmdprio_percentage[DDIR_READ] +
+		o->cmdprio_percentage[DDIR_WRITE];
+	if (p &&
+	    (fio_option_is_set(to, ioprio) ||
+	     fio_option_is_set(to, ioprio_class))) {
 		log_err("%s: cmdprio_percentage option and mutually exclusive "
-				"prio or prioclass option is set, exiting\n", to->name);
+			"prio or prioclass option is set, exiting\n",
+			to->name);
 		td_verror(td, EINVAL, "fio_libaio_init");
 		return 1;
 	}
diff --git a/fio.1 b/fio.1
index d9a3593e..a4b2deb1 100644
--- a/fio.1
+++ b/fio.1
@@ -1918,13 +1918,13 @@ In addition, there are some parameters which are only valid when a specific
 with the caveat that when used on the command line, they must come after the
 \fBioengine\fR that defines them is selected.
 .TP
-.BI (io_uring,libaio)cmdprio_percentage \fR=\fPint
-Set the percentage of I/O that will be issued with higher priority by setting
-the priority bit. Non-read I/O is likely unaffected by ``cmdprio_percentage``.
-This option cannot be used with the `prio` or `prioclass` options. For this
-option to set the priority bit properly, NCQ priority must be supported and
-enabled and `direct=1' option must be used. fio must also be run as the root
-user.
+.BI (io_uring,libaio)cmdprio_percentage \fR=\fPint[,int]
+Set the percentage of I/O that will be issued with the highest priority.
+Default: 0. A single value applies to reads and writes. Comma-separated
+values may be specified for reads and writes. This option cannot be used
+with the `prio` or `prioclass` options. For this option to be effective,
+NCQ priority must be supported and enabled, and `direct=1' option must be
+used. fio must also be run as the root user.
 .TP
 .BI (io_uring)fixedbufs
 If fio is asked to do direct IO, then Linux will map pages for each IO call, and
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 07/11] libaio: introduce aioprio and aioprioclass options
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
                   ` (5 preceding siblings ...)
  2021-07-06  0:17 ` [PATCH 06/11] libaio,io_uring: improve cmdprio_percentage option Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 08/11] libaio: introduce aioprio_bssplit Damien Le Moal
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

When the cmdprio_percentage option is used, the specified percentage of
IO will be issued with the highest priority class IOPRIO_CLASS_RT. This
priority class maps to the ATA NCQ "high" priority level and allows
exercising a SATA device to measure its command latency characteristics
in the presence of low and high priority commands.

Beside ATA NCQ commands, Linux block IO schedulers also support IO
priorities and will behave differently in the presence of IOs with
different IO priority classes and values. However, cmdprio_percentage
does not allow specifying all possible priority classes and values.

To solve this, introduce the libaio engine specific options
aioprioclass and aioprio. These new options are the equivalent of the
prio and prioclass options and allow specifying the priority class and
priority value to use for asynchronous I/Os when the aioprio_percentage
option is used. If not specified, the I/O priority class defaults to
IOPRIO_CLASS_RT and the I/O priority value to 0, as before. Similarly
to the cmdprio_percentage option, these options can specify different
values for reads and writes using a comma separated list.

To allow scripts to be written with a consistent set of option names,
add the aioprio_percentage alias for the cmdprio_percentage option.

The manpage, HOWTO and fiograph configuration file are updated to
document these new options.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 HOWTO                        | 32 ++++++++++++++--
 engines/libaio.c             | 71 +++++++++++++++++++++++++++++++-----
 fio.1                        | 27 +++++++++++++-
 tools/fiograph/fiograph.conf |  2 +-
 4 files changed, 115 insertions(+), 17 deletions(-)

diff --git a/HOWTO b/HOWTO
index 36ad8176..aaf87d95 100644
--- a/HOWTO
+++ b/HOWTO
@@ -2162,6 +2162,30 @@ with the caveat that when used on the command line, they must come after the
 	When :option:`sqthread_poll` is set, this option provides a way to
 	define which CPU should be used for the polling thread.
 
+.. option:: aioprio_percentage=int[,int] : [libaio]
+
+	Alias for :option:`cmdprio_percentage`.
+
+.. option:: aioprioclass=int[,int] : [libaio]
+
+	Set the I/O priority class to use for I/Os that must be issued with
+	a priority when :option:`aioprio_percentage` is set. If not specified
+	when :option:`aioprio_percentage` is set, this defaults to the highest
+	priority class. A single value applies to reads and writes.
+	Comma-separated values may be specified for reads and writes.See
+	:manpage:`ionice(1)`. See also the :option:`prioclass` option.
+
+.. option:: aioprio=int[,int] : [libaio]
+
+	Set the I/O priority value to use for I/Os that must be issued with
+	a priority when :option:`aioprio_percentage` is set. If not specified
+	when :option:`aioprio_percentage` is set, this defaults to 0.
+	Linux limits us to a positive value between 0 and 7, with 0 being the
+	highest. A single value applies to reads and writes. Comma-separated
+	values may be specified for reads and writes. See :manpage:`ionice(1)`.
+	Refer to an appropriate manpage for other operating systems since
+	meaning of priority may differ. See also the :option:`prio` option.
+
 .. option:: userspace_reap : [libaio]
 
 	Normally, with the libaio engine in use, fio will use the
@@ -2906,14 +2930,14 @@ Threads, processes and job synchronization
 	between 0 and 7, with 0 being the highest.  See man
 	:manpage:`ionice(1)`. Refer to an appropriate manpage for other operating
 	systems since meaning of priority may differ. For per-command priority
-	setting, see I/O engine specific `cmdprio_percentage` and `hipri_percentage`
-	options.
+	setting, see I/O engine specific :option:`cmdprio_percentage`,
+	:option:`aioprio` and :option:`hipri_percentage` options.
 
 .. option:: prioclass=int
 
 	Set the I/O priority class. See man :manpage:`ionice(1)`. For per-command
-	priority setting, see I/O engine specific `cmdprio_percentage` and
-	`hipri_percentage` options.
+	priority setting, see I/O engine specific :option:`cmdprio_percentage`,
+	:option:`aioprioclass` and :option:`hipri_percentage` options.
 
 .. option:: cpus_allowed=str
 
diff --git a/engines/libaio.c b/engines/libaio.c
index 1e997cce..96f799de 100644
--- a/engines/libaio.c
+++ b/engines/libaio.c
@@ -55,7 +55,9 @@ struct libaio_data {
 struct libaio_options {
 	void *pad;
 	unsigned int userspace_reap;
-	unsigned int cmdprio_percentage[DDIR_RWDIR_CNT];
+	unsigned int aioprio_percentage[DDIR_RWDIR_CNT];
+	unsigned int aioprio_class[DDIR_RWDIR_CNT];
+	unsigned int aioprio[DDIR_RWDIR_CNT];
 	unsigned int nowait;
 };
 
@@ -72,16 +74,43 @@ static struct fio_option options[] = {
 #ifdef FIO_HAVE_IOPRIO_CLASS
 	{
 		.name	= "cmdprio_percentage",
+		.alias	= "aioprio_percentage",
 		.lname	= "high priority percentage",
 		.type	= FIO_OPT_INT,
-		.off1	= offsetof(struct libaio_options, cmdprio_percentage[DDIR_READ]),
-		.off2	= offsetof(struct libaio_options, cmdprio_percentage[DDIR_WRITE]),
+		.off1	= offsetof(struct libaio_options, aioprio_percentage[DDIR_READ]),
+		.off2	= offsetof(struct libaio_options, aioprio_percentage[DDIR_WRITE]),
 		.minval	= 0,
 		.maxval	= 100,
 		.help	= "Send high priority I/O this percentage of the time",
 		.category = FIO_OPT_C_ENGINE,
 		.group	= FIO_OPT_G_LIBAIO,
 	},
+	{
+		.name	= "aioprioclass",
+		.lname	= "Asynchronous I/O priority class",
+		.type	= FIO_OPT_INT,
+		.off1	= offsetof(struct libaio_options, aioprio_class[DDIR_READ]),
+		.off2	= offsetof(struct libaio_options, aioprio_class[DDIR_WRITE]),
+		.help	= "Set asynchronous IO priority class",
+		.minval	= IOPRIO_MIN_PRIO_CLASS + 1,
+		.maxval	= IOPRIO_MAX_PRIO_CLASS,
+		.interval = 1,
+		.category = FIO_OPT_C_ENGINE,
+		.group	= FIO_OPT_G_CRED,
+	},
+	{
+		.name	= "aioprio",
+		.lname	= "Asynchronous I/O priority value",
+		.type	= FIO_OPT_INT,
+		.off1	= offsetof(struct libaio_options, aioprio[DDIR_READ]),
+		.off2	= offsetof(struct libaio_options, aioprio[DDIR_WRITE]),
+		.help	= "Set asynchronous IO priority value",
+		.minval	= IOPRIO_MIN_PRIO,
+		.maxval	= IOPRIO_MAX_PRIO,
+		.interval = 1,
+		.category = FIO_OPT_C_ENGINE,
+		.group	= FIO_OPT_G_CRED,
+	},
 #else
 	{
 		.name	= "cmdprio_percentage",
@@ -89,6 +118,18 @@ static struct fio_option options[] = {
 		.type	= FIO_OPT_UNSUPPORTED,
 		.help	= "Your platform does not support I/O priority classes",
 	},
+		{
+		.name	= "aioprioclass",
+		.lname	= "Asynchronous I/O priority class",
+		.type	= FIO_OPT_UNSUPPORTED,
+		.help	= "Your platform does not support I/O priority classes",
+	},
+	{
+		.name	= "aioprio",
+		.lname	= "Asynchronous I/O priority level",
+		.type	= FIO_OPT_UNSUPPORTED,
+		.help	= "Your platform does not support I/O priority classes",
+	},
 #endif
 	{
 		.name	= "nowait",
@@ -136,10 +177,12 @@ static int fio_libaio_prep(struct thread_data *td, struct io_u *io_u)
 static void fio_libaio_prio_prep(struct thread_data *td, struct io_u *io_u)
 {
 	struct libaio_options *o = td->eo;
-	unsigned int p = o->cmdprio_percentage[io_u->ddir];
+	enum fio_ddir ddir = io_u->ddir;
+	unsigned int p = o->aioprio_percentage[ddir];
 
 	if (p && rand_between(&td->prio_state, 0, 99) < p) {
-		io_u->iocb.aio_reqprio = ioprio_value(IOPRIO_CLASS_RT, 0);
+		io_u->iocb.aio_reqprio =
+			ioprio_value(o->aioprio_class[ddir], o->aioprio[ddir]);
 		io_u->iocb.u.c.flags |= IOCB_FLAG_IOPRIO;
 		io_u->flags |= IO_U_F_PRIORITY;
 	}
@@ -279,7 +322,7 @@ static enum fio_q_status fio_libaio_queue(struct thread_data *td,
 		return FIO_Q_COMPLETED;
 	}
 
-	if (o->cmdprio_percentage[io_u->ddir])
+	if (o->aioprio_percentage[io_u->ddir])
 		fio_libaio_prio_prep(td, io_u);
 
 	ld->iocbs[ld->head] = &io_u->iocb;
@@ -421,10 +464,10 @@ static int fio_libaio_post_init(struct thread_data *td)
 
 static int fio_libaio_init(struct thread_data *td)
 {
+	struct libaio_options *o = td->eo;
 	struct libaio_data *ld;
 	struct thread_options *to = &td->o;
-	struct libaio_options *o = td->eo;
-	int p;
+	int i, p = 0;
 
 	ld = calloc(1, sizeof(*ld));
 
@@ -436,11 +479,19 @@ static int fio_libaio_init(struct thread_data *td)
 
 	td->io_ops_data = ld;
 
+	/*
+	 * If aioprio_percentage is set and aioprio_class is not set,
+	 * default to RT priority class.
+	 */
+	for (i = 0; i < DDIR_RWDIR_CNT; i++) {
+		if (o->aioprio_percentage[i] && !o->aioprio_class[i])
+			o->aioprio_class[i] = IOPRIO_CLASS_RT;
+		p += o->aioprio_percentage[i];
+	}
+
 	/*
 	 * Check for option conflicts
 	 */
-	p = o->cmdprio_percentage[DDIR_READ] +
-		o->cmdprio_percentage[DDIR_WRITE];
 	if (p &&
 	    (fio_option_is_set(to, ioprio) ||
 	     fio_option_is_set(to, ioprio_class))) {
diff --git a/fio.1 b/fio.1
index a4b2deb1..0f4b9ff7 100644
--- a/fio.1
+++ b/fio.1
@@ -1955,6 +1955,27 @@ the cost of using more CPU in the system.
 When `sqthread_poll` is set, this option provides a way to define which CPU
 should be used for the polling thread.
 .TP
+.BI (libaio)aioprio_percentage \fR=\fPint[,int]
+Alias for \fBcmdprio_percentage\fR.
+.TP
+.BI (libaio)aioprioclass \fR=\fPint[,int]
+Set the I/O priority class to use for I/Os that must be issued with a
+priority when \fBaioprio_percentage\fR is set. If not specified when
+\fBaioprio_percentage\fR is set, this defaults to the highest priority
+class. A single value applies to reads and writes. Comma-separated
+values may be specified for reads and writes. See man \fBionice\fR\|(1).
+See also the \fBprioclass\fR option.
+.TP
+.BI (libaio)aioprio \fR=\fPint[,int]
+Set the I/O priority value to use for I/Os that must be issued with a
+priority when \fBaioprio_percentage\fR is set. If not specified when
+\fBaioprio_percentage\fR is set, this defaults to 0. Linux limits us to
+a positive value between 0 and 7, with 0 being the highest. A single
+value applies to reads and writes. Comma-separated values may be specified
+for reads and writes. See man \fBionice\fR\|(1). Refer to an appropriate
+manpage for other operating systems since the meaning of priority may differ.
+See also the \fBprio\fR option.
+.TP
 .BI (libaio)userspace_reap
 Normally, with the libaio engine in use, fio will use the
 \fBio_getevents\fR\|(3) system call to reap newly returned events. With
@@ -2624,11 +2645,13 @@ Set the I/O priority value of this job. Linux limits us to a positive value
 between 0 and 7, with 0 being the highest. See man
 \fBionice\fR\|(1). Refer to an appropriate manpage for other operating
 systems since meaning of priority may differ. For per-command priority
-setting, see the I/O engine specific `cmdprio_percentage` option.
+setting, see the I/O engine specific `cmdprio_percentage` and
+`aioprio` options.
 .TP
 .BI prioclass \fR=\fPint
 Set the I/O priority class. See man \fBionice\fR\|(1). For per-command
-priority setting, see the I/O engine specific `cmdprio_percentage` option.
+priority setting, see the I/O engine specific `cmdprio_percentage` and
+`aioprioclass` options.
 .TP
 .BI cpus_allowed \fR=\fPstr
 Controls the same options as \fBcpumask\fR, but accepts a textual
diff --git a/tools/fiograph/fiograph.conf b/tools/fiograph/fiograph.conf
index 1d50d141..7f0434d5 100644
--- a/tools/fiograph/fiograph.conf
+++ b/tools/fiograph/fiograph.conf
@@ -51,7 +51,7 @@ specific_options=ime_psync  ime_psyncv
 specific_options=hipri  cmdprio_percentage  fixedbufs  registerfiles  sqthread_poll  sqthread_poll_cpu  nonvectored  uncached  nowait  force_async
 
 [ioengine_libaio]
-specific_options=userspace_reap  cmdprio_percentage  nowait
+specific_options=userspace_reap  cmdprio_percentage  aioprio_percentage  nowait aioprioclass aioprio
 
 [ioengine_libcufile]
 specific_options=gpu_dev_ids  cuda_io
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 08/11] libaio: introduce aioprio_bssplit
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
                   ` (6 preceding siblings ...)
  2021-07-06  0:17 ` [PATCH 07/11] libaio: introduce aioprio and aioprioclass options Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 09/11] libaio: relax cdmprio_percentage constraints Damien Le Moal
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

The cmdprio_percentage, aioprioclass and aioprio options allow
specifying different values for read and write operations. This enables
various IO priority issuing patterns even uner a mixed read-write
workload but does not allow differentiation within read and write
operation types of IOs with different sizes when the bssplit option is
used.

Add the aioprio_bssplit to complement the use of the bssplit option.
This new option has the same format as the bssplit option, but the
percentage value indicates the percentage of IO operation with a
cparticular block size that must be issued with the priority class and
value specified by aioprioclass and aioprio.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 HOWTO                        |  11 +++
 engines/libaio.c             | 130 +++++++++++++++++++++++++++++++++--
 fio.1                        |  10 +++
 tools/fiograph/fiograph.conf |   2 +-
 4 files changed, 145 insertions(+), 8 deletions(-)

diff --git a/HOWTO b/HOWTO
index aaf87d95..9a7158aa 100644
--- a/HOWTO
+++ b/HOWTO
@@ -2186,6 +2186,17 @@ with the caveat that when used on the command line, they must come after the
 	Refer to an appropriate manpage for other operating systems since
 	meaning of priority may differ. See also the :option:`prio` option.
 
+.. option:: aioprio_bssplit=str[,str]
+	To get a finer control over AIO priority, this option allows
+	specifying the percentage of IOs that must have a priority set
+	depending on the block size of the IO. This option is useful only
+	when used together with the :option:`bssplit` option, that is,
+	multiple different block sizes are used for reads and writes.
+	The format for this option is the same as the format of the
+	:option:`bssplit` option, with the exception that values for
+	trim IOs are ignored. This option is mutually exclusive with the
+	:option:`cmdprio_percentage` option.
+
 .. option:: userspace_reap : [libaio]
 
 	Normally, with the libaio engine in use, fio will use the
diff --git a/engines/libaio.c b/engines/libaio.c
index 96f799de..e0f8a3d3 100644
--- a/engines/libaio.c
+++ b/engines/libaio.c
@@ -50,17 +50,84 @@ struct libaio_data {
 	unsigned int queued;
 	unsigned int head;
 	unsigned int tail;
+
+	bool use_aioprio;
 };
 
 struct libaio_options {
-	void *pad;
+	struct thread_data *td;
 	unsigned int userspace_reap;
 	unsigned int aioprio_percentage[DDIR_RWDIR_CNT];
 	unsigned int aioprio_class[DDIR_RWDIR_CNT];
 	unsigned int aioprio[DDIR_RWDIR_CNT];
+	unsigned int aioprio_bssplit_nr[DDIR_RWDIR_CNT];
+	struct bssplit *aioprio_bssplit[DDIR_RWDIR_CNT];
 	unsigned int nowait;
 };
 
+static int libaio_aioprio_bssplit_ddir(struct thread_options *to, void *eo,
+				       enum fio_ddir ddir, char *str, bool data)
+{
+	struct libaio_options *o = eo;
+	struct split split;
+	unsigned int i;
+
+	if (ddir == DDIR_TRIM)
+		return 0;
+
+	memset(&split, 0, sizeof(split));
+
+	if (split_parse_ddir(to, &split, str, data, BSSPLIT_MAX))
+		return 1;
+	if (!split.nr)
+		return 0;
+
+	o->aioprio_bssplit_nr[ddir] = split.nr;
+	o->aioprio_bssplit[ddir] = malloc(split.nr * sizeof(struct bssplit));
+	if (!o->aioprio_bssplit[ddir])
+		return 1;
+
+	for (i = 0; i < split.nr; i++) {
+		o->aioprio_bssplit[ddir][i].bs = split.val1[i];
+		if (split.val2[i] == -1U) {
+			o->aioprio_bssplit[ddir][i].perc = 0;
+		} else {
+			if (split.val2[i] > 100)
+				o->aioprio_bssplit[ddir][i].perc = 100;
+			else
+				o->aioprio_bssplit[ddir][i].perc = split.val2[i];
+		}
+	}
+
+	return 0;
+}
+
+static int str_aioprio_bssplit_cb(void *data, const char *input)
+{
+	struct libaio_options *o = data;
+	struct thread_data *td = o->td;
+	char *str, *p;
+	int i, ret = 0;
+
+	p = str = strdup(input);
+
+	strip_blank_front(&str);
+	strip_blank_end(str);
+
+	ret = str_split_parse(td, str, libaio_aioprio_bssplit_ddir, o, false);
+
+	if (parse_dryrun()) {
+		for (i = 0; i < DDIR_RWDIR_CNT; i++) {
+			free(o->aioprio_bssplit[i]);
+			o->aioprio_bssplit[i] = NULL;
+			o->aioprio_bssplit_nr[i] = 0;
+		}
+	}
+
+	free(p);
+	return ret;
+}
+
 static struct fio_option options[] = {
 	{
 		.name	= "userspace_reap",
@@ -96,7 +163,7 @@ static struct fio_option options[] = {
 		.maxval	= IOPRIO_MAX_PRIO_CLASS,
 		.interval = 1,
 		.category = FIO_OPT_C_ENGINE,
-		.group	= FIO_OPT_G_CRED,
+		.group	= FIO_OPT_G_LIBAIO,
 	},
 	{
 		.name	= "aioprio",
@@ -109,7 +176,17 @@ static struct fio_option options[] = {
 		.maxval	= IOPRIO_MAX_PRIO,
 		.interval = 1,
 		.category = FIO_OPT_C_ENGINE,
-		.group	= FIO_OPT_G_CRED,
+		.group	= FIO_OPT_G_LIBAIO,
+	},
+	{
+		.name   = "aioprio_bssplit",
+		.lname  = "Priority percentage block size split",
+		.type   = FIO_OPT_STR_ULL,
+		.cb     = str_aioprio_bssplit_cb,
+		.off1   = offsetof(struct libaio_options, aioprio_bssplit),
+		.help   = "Set priority percentages for different block sizes",
+		.category = FIO_OPT_C_ENGINE,
+		.group	= FIO_OPT_G_LIBAIO,
 	},
 #else
 	{
@@ -130,6 +207,12 @@ static struct fio_option options[] = {
 		.type	= FIO_OPT_UNSUPPORTED,
 		.help	= "Your platform does not support I/O priority classes",
 	},
+	{
+		.name   = "aioprio_bssplit",
+		.lname  = "Priority percentage block size split",
+		.type	= FIO_OPT_UNSUPPORTED,
+		.help	= "Your platform does not support I/O priority classes",
+	},
 #endif
 	{
 		.name	= "nowait",
@@ -174,11 +257,33 @@ static int fio_libaio_prep(struct thread_data *td, struct io_u *io_u)
 	return 0;
 }
 
+static int fio_libaio_need_prio(struct libaio_options *o, struct io_u *io_u)
+{
+	enum fio_ddir ddir = io_u->ddir;
+	unsigned int p = o->aioprio_percentage[ddir];
+	int i;
+
+	/*
+	 * If cmdprio_percentage option was specified, then use that
+	 * percentage. Otherwise, use aioprio_bssplit percentages depending
+	 * on the IO size.
+	 */
+	if (p)
+		return p;
+
+	for (i = 0; i < o->aioprio_bssplit_nr[ddir]; i++) {
+		if (o->aioprio_bssplit[ddir][i].bs == io_u->buflen)
+			return o->aioprio_bssplit[ddir][i].perc;
+	}
+
+	return 0;
+}
+
 static void fio_libaio_prio_prep(struct thread_data *td, struct io_u *io_u)
 {
 	struct libaio_options *o = td->eo;
 	enum fio_ddir ddir = io_u->ddir;
-	unsigned int p = o->aioprio_percentage[ddir];
+	unsigned int p = fio_libaio_need_prio(o, io_u);
 
 	if (p && rand_between(&td->prio_state, 0, 99) < p) {
 		io_u->iocb.aio_reqprio =
@@ -291,7 +396,6 @@ static enum fio_q_status fio_libaio_queue(struct thread_data *td,
 					  struct io_u *io_u)
 {
 	struct libaio_data *ld = td->io_ops_data;
-	struct libaio_options *o = td->eo;
 
 	fio_ro_check(td, io_u);
 
@@ -322,7 +426,7 @@ static enum fio_q_status fio_libaio_queue(struct thread_data *td,
 		return FIO_Q_COMPLETED;
 	}
 
-	if (o->aioprio_percentage[io_u->ddir])
+	if (ld->use_aioprio)
 		fio_libaio_prio_prep(td, io_u);
 
 	ld->iocbs[ld->head] = &io_u->iocb;
@@ -464,9 +568,10 @@ static int fio_libaio_post_init(struct thread_data *td)
 
 static int fio_libaio_init(struct thread_data *td)
 {
+	struct thread_options *to = &td->o;
 	struct libaio_options *o = td->eo;
 	struct libaio_data *ld;
-	struct thread_options *to = &td->o;
+	int nr_aioprio_bssplits = 0;
 	int i, p = 0;
 
 	ld = calloc(1, sizeof(*ld));
@@ -487,11 +592,19 @@ static int fio_libaio_init(struct thread_data *td)
 		if (o->aioprio_percentage[i] && !o->aioprio_class[i])
 			o->aioprio_class[i] = IOPRIO_CLASS_RT;
 		p += o->aioprio_percentage[i];
+		nr_aioprio_bssplits += o->aioprio_bssplit_nr[i];
 	}
 
 	/*
 	 * Check for option conflicts
 	 */
+	if (p && nr_aioprio_bssplits) {
+		log_err("%s: cmdprio_percentage and aioprio_bssplit options "
+			"are mutually exclusive\n",
+			to->name);
+		td_verror(td, EINVAL, "fio_libaio_init");
+		return 1;
+	}
 	if (p &&
 	    (fio_option_is_set(to, ioprio) ||
 	     fio_option_is_set(to, ioprio_class))) {
@@ -501,6 +614,9 @@ static int fio_libaio_init(struct thread_data *td)
 		td_verror(td, EINVAL, "fio_libaio_init");
 		return 1;
 	}
+
+	ld->use_aioprio = p || nr_aioprio_bssplits;
+
 	return 0;
 }
 
diff --git a/fio.1 b/fio.1
index 0f4b9ff7..129aeb94 100644
--- a/fio.1
+++ b/fio.1
@@ -1976,6 +1976,16 @@ for reads and writes. See man \fBionice\fR\|(1). Refer to an appropriate
 manpage for other operating systems since the meaning of priority may differ.
 See also the \fBprio\fR option.
 .TP
+.BI (libaio)aioprio_bssplit \fR=\fPstr[,str]
+To get a finer control over AIO priority, this option allows specifying
+the percentage of IOs that must have a priority set depending on the block
+size of the IO. This option is useful only when used together with the option
+\fBbssplit\fR, that is, multiple different block sizes are used for reads and
+writes. The format for this option is the same as the format of the
+\fBbssplit\fR option, with the exception that values for trim IOs are
+ignored. This option is mutually exclusive with the \fBcmdprio_percentage\fR
+option.
+.TP
 .BI (libaio)userspace_reap
 Normally, with the libaio engine in use, fio will use the
 \fBio_getevents\fR\|(3) system call to reap newly returned events. With
diff --git a/tools/fiograph/fiograph.conf b/tools/fiograph/fiograph.conf
index 7f0434d5..4bfecdd8 100644
--- a/tools/fiograph/fiograph.conf
+++ b/tools/fiograph/fiograph.conf
@@ -51,7 +51,7 @@ specific_options=ime_psync  ime_psyncv
 specific_options=hipri  cmdprio_percentage  fixedbufs  registerfiles  sqthread_poll  sqthread_poll_cpu  nonvectored  uncached  nowait  force_async
 
 [ioengine_libaio]
-specific_options=userspace_reap  cmdprio_percentage  aioprio_percentage  nowait aioprioclass aioprio
+specific_options=userspace_reap  cmdprio_percentage  aioprio_percentage  nowait aioprioclass aiopri0  aioprio_bssplit
 
 [ioengine_libcufile]
 specific_options=gpu_dev_ids  cuda_io
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 09/11] libaio: relax cdmprio_percentage constraints
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
                   ` (7 preceding siblings ...)
  2021-07-06  0:17 ` [PATCH 08/11] libaio: introduce aioprio_bssplit Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 10/11] fio: Introduce the log_prio option Damien Le Moal
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

When an AIO is issued without a priority set, Linux kernel will execute
it using the issuing context IO priority set with ioprio_set(). In fio,
a job IO priority is controlled with the prioclass and prio options and
these options cannot be used together with the cmdprio_percentage
option.

Allow a user to have AIO priorities to default to the job defined IO
priority by removing the mutual exclusion between the options
cmdprio_percentage and prioclass/prio.

With the introduction of the aioprioclass option, an AIO priority may be
lower than the job default priority, resulting in reversed clat
statistics showed for high and low priority IOs when fio completes.
Solve this by setting an io_u IO_U_F_PRIORITY flag depending on a
comparison between the aio priority and job default IO priority. The job
default IO priority is added as the ioprio field in struct thread_data
for convenience, avoiding referencing the job options for every IO.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 backend.c        |  1 +
 engines/libaio.c | 28 ++++++++++++++++------------
 fio.h            |  5 +++++
 3 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/backend.c b/backend.c
index 6290e0d6..ff53e8b5 100644
--- a/backend.c
+++ b/backend.c
@@ -1760,6 +1760,7 @@ static void *thread_main(void *data)
 			td_verror(td, errno, "ioprio_set");
 			goto err;
 		}
+		td->ioprio = ioprio_value(o->ioprio_class, o->ioprio);
 	}
 
 	if (o->cgroup && cgroup_setup(td, cgroup_list, &cgroup_mnt))
diff --git a/engines/libaio.c b/engines/libaio.c
index e0f8a3d3..c0cbf97b 100644
--- a/engines/libaio.c
+++ b/engines/libaio.c
@@ -282,13 +282,26 @@ static int fio_libaio_need_prio(struct libaio_options *o, struct io_u *io_u)
 static void fio_libaio_prio_prep(struct thread_data *td, struct io_u *io_u)
 {
 	struct libaio_options *o = td->eo;
-	enum fio_ddir ddir = io_u->ddir;
 	unsigned int p = fio_libaio_need_prio(o, io_u);
+	enum fio_ddir ddir = io_u->ddir;
+	unsigned int aioprio =
+		ioprio_value(o->aioprio_class[ddir], o->aioprio[ddir]);
 
 	if (p && rand_between(&td->prio_state, 0, 99) < p) {
-		io_u->iocb.aio_reqprio =
-			ioprio_value(o->aioprio_class[ddir], o->aioprio[ddir]);
+		io_u->iocb.aio_reqprio = aioprio;
 		io_u->iocb.u.c.flags |= IOCB_FLAG_IOPRIO;
+		if (!td->ioprio || aioprio < td->ioprio) {
+			/*
+			 * The AIO priortity is higher than the default context
+			 * priority.
+			 */
+			io_u->flags |= IO_U_F_PRIORITY;
+		}
+	} else if (td->ioprio && td->ioprio < aioprio) {
+		/*
+		 * The IO will be executed with the default context priority
+		 * and it is higher than the aio priority.
+		 */
 		io_u->flags |= IO_U_F_PRIORITY;
 	}
 }
@@ -605,15 +618,6 @@ static int fio_libaio_init(struct thread_data *td)
 		td_verror(td, EINVAL, "fio_libaio_init");
 		return 1;
 	}
-	if (p &&
-	    (fio_option_is_set(to, ioprio) ||
-	     fio_option_is_set(to, ioprio_class))) {
-		log_err("%s: cmdprio_percentage option and mutually exclusive "
-			"prio or prioclass option is set, exiting\n",
-			to->name);
-		td_verror(td, EINVAL, "fio_libaio_init");
-		return 1;
-	}
 
 	ld->use_aioprio = p || nr_aioprio_bssplits;
 
diff --git a/fio.h b/fio.h
index 83334652..fa7e42dd 100644
--- a/fio.h
+++ b/fio.h
@@ -274,6 +274,11 @@ struct thread_data {
 
 	int shm_id;
 
+	/*
+	 * Job default IO priority set with prioclass and prio options.
+	 */
+	unsigned int ioprio;
+
 	/*
 	 * IO engine hooks, contains everything needed to submit an io_u
 	 * to any of the available IO engines.
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 10/11] fio: Introduce the log_prio option
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
                   ` (8 preceding siblings ...)
  2021-07-06  0:17 ` [PATCH 09/11] libaio: relax cdmprio_percentage constraints Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-06  0:17 ` [PATCH 11/11] examples: add libaio priority use examples Damien Le Moal
  2021-07-19  3:24 ` [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

Introduce the log_prio option to expand priority logging from just a
single bit information (priority high vs low) to the full value of the
priority value used to execute IOs. When this option is set, the
priority value is printed as a 16-bits hexadecimal value combining
the I/O priority class and priority level as defined by the
ioprio_value() helper.

Similarly to the log_offset option, this option does not result in
actual I/O priority logging when log_avg_msec is set.

This patch also fixes a problem with the IO_U_F_PRIORITY flag, namely
that this flag is used to indicate that the IO is being executed with a
high priority on the device while at the same time indicating how to
account for the IO completion latency (high_prio clat vs low_prio clat).
With the introduction of the aioprioclass and aioprio options, these
assumptions are not necesarilly compatible anymore.
These problems are addressed as follows:
* The priority_bit field of struct iosample is replaced with the
  16-bits priority field representing the full io_u->ioprio value. When
  log_prio is set, the priority field value is logged as is. When
  log_prio is not set, 1 is logged as the entry's priority field if the
  sample priority class is IOPRIO_CLASS_RT, and 0 otherwise.
* IO_U_F_PRIORITY is renamed to IO_U_F_HIGH_PRIO to indicate that a job
  IO has the highest priority within the job context and so must be
  accounted as such using high_prio clat.

While fio final statistics only show accounting of high vs low IO
completion latency statistics, the log_prio option allows a user to
perform more detailed statistical analysis of a workload using
multiple different IO priorities.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 cconv.c              |  2 ++
 client.c             |  2 ++
 engines/filecreate.c |  2 +-
 engines/filedelete.c |  2 +-
 engines/filestat.c   |  2 +-
 engines/io_uring.c   |  6 ++--
 engines/libaio.c     |  5 +--
 eta.c                |  2 +-
 fio.1                | 15 +++++++--
 init.c               |  4 +++
 io_u.c               | 14 ++++++---
 io_u.h               | 10 ++++--
 iolog.c              | 45 ++++++++++++++++++++------
 iolog.h              | 16 ++++++++--
 options.c            | 10 ++++++
 os/os-android.h      |  5 +++
 os/os-linux.h        |  5 +++
 os/os.h              |  3 ++
 server.h             |  3 +-
 stat.c               | 75 +++++++++++++++++++++++---------------------
 stat.h               |  9 +++---
 thread_options.h     |  4 +++
 22 files changed, 170 insertions(+), 71 deletions(-)

diff --git a/cconv.c b/cconv.c
index 74c24106..c5d52c84 100644
--- a/cconv.c
+++ b/cconv.c
@@ -192,6 +192,7 @@ void convert_thread_options_to_cpu(struct thread_options *o,
 	o->log_hist_coarseness = le32_to_cpu(top->log_hist_coarseness);
 	o->log_max = le32_to_cpu(top->log_max);
 	o->log_offset = le32_to_cpu(top->log_offset);
+	o->log_prio = le32_to_cpu(top->log_prio);
 	o->log_gz = le32_to_cpu(top->log_gz);
 	o->log_gz_store = le32_to_cpu(top->log_gz_store);
 	o->log_unix_epoch = le32_to_cpu(top->log_unix_epoch);
@@ -415,6 +416,7 @@ void convert_thread_options_to_net(struct thread_options_pack *top,
 	top->log_avg_msec = cpu_to_le32(o->log_avg_msec);
 	top->log_max = cpu_to_le32(o->log_max);
 	top->log_offset = cpu_to_le32(o->log_offset);
+	top->log_prio = cpu_to_le32(o->log_prio);
 	top->log_gz = cpu_to_le32(o->log_gz);
 	top->log_gz_store = cpu_to_le32(o->log_gz_store);
 	top->log_unix_epoch = cpu_to_le32(o->log_unix_epoch);
diff --git a/client.c b/client.c
index 29d8750a..8b230617 100644
--- a/client.c
+++ b/client.c
@@ -1679,6 +1679,7 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd,
 	ret->log_type		= le32_to_cpu(ret->log_type);
 	ret->compressed		= le32_to_cpu(ret->compressed);
 	ret->log_offset		= le32_to_cpu(ret->log_offset);
+	ret->log_prio		= le32_to_cpu(ret->log_prio);
 	ret->log_hist_coarseness = le32_to_cpu(ret->log_hist_coarseness);
 
 	if (*store_direct)
@@ -1696,6 +1697,7 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd,
 		s->data.val	= le64_to_cpu(s->data.val);
 		s->__ddir	= __le32_to_cpu(s->__ddir);
 		s->bs		= le64_to_cpu(s->bs);
+		s->priority	= le16_to_cpu(s->priority);
 
 		if (ret->log_offset) {
 			struct io_sample_offset *so = (void *) s;
diff --git a/engines/filecreate.c b/engines/filecreate.c
index 16c64928..4bb13c34 100644
--- a/engines/filecreate.c
+++ b/engines/filecreate.c
@@ -49,7 +49,7 @@ static int open_file(struct thread_data *td, struct fio_file *f)
 		uint64_t nsec;
 
 		nsec = ntime_since_now(&start);
-		add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0);
+		add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0, false);
 	}
 
 	return 0;
diff --git a/engines/filedelete.c b/engines/filedelete.c
index 64c58639..e882ccf0 100644
--- a/engines/filedelete.c
+++ b/engines/filedelete.c
@@ -51,7 +51,7 @@ static int delete_file(struct thread_data *td, struct fio_file *f)
 		uint64_t nsec;
 
 		nsec = ntime_since_now(&start);
-		add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0);
+		add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0, false);
 	}
 
 	return 0;
diff --git a/engines/filestat.c b/engines/filestat.c
index 405f028d..00311247 100644
--- a/engines/filestat.c
+++ b/engines/filestat.c
@@ -125,7 +125,7 @@ static int stat_file(struct thread_data *td, struct fio_file *f)
 		uint64_t nsec;
 
 		nsec = ntime_since_now(&start);
-		add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0);
+		add_clat_sample(td, data->stat_ddir, nsec, 0, 0, 0, false);
 	}
 
 	return 0;
diff --git a/engines/io_uring.c b/engines/io_uring.c
index d083a65f..c44768d8 100644
--- a/engines/io_uring.c
+++ b/engines/io_uring.c
@@ -270,6 +270,7 @@ static int fio_ioring_prep(struct thread_data *td, struct io_u *io_u)
 			sqe->ioprio = td->o.ioprio_class << 13;
 		if (ld->ioprio_set)
 			sqe->ioprio |= td->o.ioprio;
+		io_u->ioprio = sqe->ioprio;
 		sqe->off = io_u->offset;
 		sqe->rw_flags = 0;
 	} else if (ddir_sync(io_u->ddir)) {
@@ -384,8 +385,9 @@ static void fio_ioring_prio_prep(struct thread_data *td, struct io_u *io_u)
 	unsigned int p = o->cmdprio_percentage[io_u->ddir];
 
 	if (p && rand_between(&td->prio_state, 0, 99) < p) {
-		ld->sqes[io_u->index].ioprio = ioprio_value(IOPRIO_CLASS_RT, 0);
-		io_u->flags |= IO_U_F_PRIORITY;
+		io_u->ioprio = ioprio_value(IOPRIO_CLASS_RT, 0);
+		ld->sqes[io_u->index].ioprio = io_u->ioprio;
+		io_u->flags |= IO_U_F_HIGH_PRIO;
 	}
 }
 
diff --git a/engines/libaio.c b/engines/libaio.c
index c0cbf97b..123705ea 100644
--- a/engines/libaio.c
+++ b/engines/libaio.c
@@ -288,6 +288,7 @@ static void fio_libaio_prio_prep(struct thread_data *td, struct io_u *io_u)
 		ioprio_value(o->aioprio_class[ddir], o->aioprio[ddir]);
 
 	if (p && rand_between(&td->prio_state, 0, 99) < p) {
+		io_u->ioprio = aioprio;
 		io_u->iocb.aio_reqprio = aioprio;
 		io_u->iocb.u.c.flags |= IOCB_FLAG_IOPRIO;
 		if (!td->ioprio || aioprio < td->ioprio) {
@@ -295,14 +296,14 @@ static void fio_libaio_prio_prep(struct thread_data *td, struct io_u *io_u)
 			 * The AIO priortity is higher than the default context
 			 * priority.
 			 */
-			io_u->flags |= IO_U_F_PRIORITY;
+			io_u->flags |= IO_U_F_HIGH_PRIO;
 		}
 	} else if (td->ioprio && td->ioprio < aioprio) {
 		/*
 		 * The IO will be executed with the default context priority
 		 * and it is higher than the aio priority.
 		 */
-		io_u->flags |= IO_U_F_PRIORITY;
+		io_u->flags |= IO_U_F_HIGH_PRIO;
 	}
 }
 
diff --git a/eta.c b/eta.c
index db13cb18..ea1781f3 100644
--- a/eta.c
+++ b/eta.c
@@ -509,7 +509,7 @@ bool calc_thread_status(struct jobs_eta *je, int force)
 		memcpy(&rate_prev_time, &now, sizeof(now));
 		regrow_agg_logs();
 		for_each_rw_ddir(ddir) {
-			add_agg_sample(sample_val(je->rate[ddir]), ddir, 0, 0);
+			add_agg_sample(sample_val(je->rate[ddir]), ddir, 0);
 		}
 	}
 
diff --git a/fio.1 b/fio.1
index 129aeb94..3cef5e2d 100644
--- a/fio.1
+++ b/fio.1
@@ -3200,6 +3200,11 @@ If this is set, the iolog options will include the byte offset for the I/O
 entry as well as the other data values. Defaults to 0 meaning that
 offsets are not present in logs. Also see \fBLOG FILE FORMATS\fR section.
 .TP
+.BI log_prio \fR=\fPbool
+If this is set, the iolog options will include the I/O priority for the I/O
+entry as well as the other data values. Defaults to 0 meaning that
+I/O priorities are not present in logs. Also see \fBLOG FILE FORMATS\fR section.
+.TP
 .BI log_compression \fR=\fPint
 If this is set, fio will compress the I/O logs as it goes, to keep the
 memory footprint lower. When a log reaches the specified size, that chunk is
@@ -4133,8 +4138,14 @@ The entry's `block size' is always in bytes. The `offset' is the position in byt
 from the start of the file for that particular I/O. The logging of the offset can be
 toggled with \fBlog_offset\fR.
 .P
-`Command priority` is 0 for normal priority and 1 for high priority. This is controlled
-by the ioengine specific \fBcmdprio_percentage\fR.
+If \fBlog_prio\fR is not set, the entry's `Command priority` is 1 for an IO executed
+with the highest RT priority class (\fBprioclass\fR=1 or \fBaioprioclass\fR=1) and 0
+otherwise. This is controlled by the \fBprioclass\fR option and the ioengine specific
+\fBcmdprio_percentage\fR \fBaioprioclass\fR options. If \fBlog_prio\fR is set, the
+entry's `Command priority` is the priority set for the IO, as a 16-bits hexadecimal
+number with the lowest 13 bits indicating the priority value (\fBprio\fR and
+\fBaioprio\fR options) and the highest 3 bits indicating the IO priority class
+(\fBprioclass\fR and \fBaioprioclass\fR options).
 .P
 Fio defaults to logging every individual I/O but when windowed logging is set
 through \fBlog_avg_msec\fR, either the average (by default) or the maximum
diff --git a/init.c b/init.c
index 60c7cff4..33320159 100644
--- a/init.c
+++ b/init.c
@@ -1557,6 +1557,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
 			.hist_coarseness = o->log_hist_coarseness,
 			.log_type = IO_LOG_TYPE_LAT,
 			.log_offset = o->log_offset,
+			.log_prio = o->log_prio,
 			.log_gz = o->log_gz,
 			.log_gz_store = o->log_gz_store,
 		};
@@ -1590,6 +1591,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
 			.hist_coarseness = o->log_hist_coarseness,
 			.log_type = IO_LOG_TYPE_HIST,
 			.log_offset = o->log_offset,
+			.log_prio = o->log_prio,
 			.log_gz = o->log_gz,
 			.log_gz_store = o->log_gz_store,
 		};
@@ -1621,6 +1623,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
 			.hist_coarseness = o->log_hist_coarseness,
 			.log_type = IO_LOG_TYPE_BW,
 			.log_offset = o->log_offset,
+			.log_prio = o->log_prio,
 			.log_gz = o->log_gz,
 			.log_gz_store = o->log_gz_store,
 		};
@@ -1652,6 +1655,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
 			.hist_coarseness = o->log_hist_coarseness,
 			.log_type = IO_LOG_TYPE_IOPS,
 			.log_offset = o->log_offset,
+			.log_prio = o->log_prio,
 			.log_gz = o->log_gz,
 			.log_gz_store = o->log_gz_store,
 		};
diff --git a/io_u.c b/io_u.c
index b60488a3..897bd1f7 100644
--- a/io_u.c
+++ b/io_u.c
@@ -1595,7 +1595,7 @@ again:
 		assert(io_u->flags & IO_U_F_FREE);
 		io_u_clear(td, io_u, IO_U_F_FREE | IO_U_F_NO_FILE_PUT |
 				 IO_U_F_TRIMMED | IO_U_F_BARRIER |
-				 IO_U_F_VER_LIST | IO_U_F_PRIORITY);
+				 IO_U_F_VER_LIST | IO_U_F_HIGH_PRIO);
 
 		io_u->error = 0;
 		io_u->acct_ddir = -1;
@@ -1799,6 +1799,10 @@ struct io_u *get_io_u(struct thread_data *td)
 	io_u->xfer_buf = io_u->buf;
 	io_u->xfer_buflen = io_u->buflen;
 
+	/*
+	 * Remember the issuing context priority. The IO engine may change this.
+	 */
+	io_u->ioprio = td->ioprio;
 out:
 	assert(io_u->file);
 	if (!td_io_prep(td, io_u)) {
@@ -1884,7 +1888,8 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,
 		unsigned long long tnsec;
 
 		tnsec = ntime_since(&io_u->start_time, &icd->time);
-		add_lat_sample(td, idx, tnsec, bytes, io_u->offset, io_u_is_prio(io_u));
+		add_lat_sample(td, idx, tnsec, bytes, io_u->offset,
+			       io_u->ioprio, io_u_is_high_prio(io_u));
 
 		if (td->flags & TD_F_PROFILE_OPS) {
 			struct prof_io_ops *ops = &td->prof_io_ops;
@@ -1905,7 +1910,8 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,
 
 	if (ddir_rw(idx)) {
 		if (!td->o.disable_clat) {
-			add_clat_sample(td, idx, llnsec, bytes, io_u->offset, io_u_is_prio(io_u));
+			add_clat_sample(td, idx, llnsec, bytes, io_u->offset,
+					io_u->ioprio, io_u_is_high_prio(io_u));
 			io_u_mark_latency(td, llnsec);
 		}
 
@@ -2162,7 +2168,7 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u)
 			td = td->parent;
 
 		add_slat_sample(td, io_u->ddir, slat_time, io_u->xfer_buflen,
-				io_u->offset, io_u_is_prio(io_u));
+				io_u->offset, io_u->ioprio);
 	}
 }
 
diff --git a/io_u.h b/io_u.h
index d4c5be43..bdbac525 100644
--- a/io_u.h
+++ b/io_u.h
@@ -21,7 +21,7 @@ enum {
 	IO_U_F_TRIMMED		= 1 << 5,
 	IO_U_F_BARRIER		= 1 << 6,
 	IO_U_F_VER_LIST		= 1 << 7,
-	IO_U_F_PRIORITY		= 1 << 8,
+	IO_U_F_HIGH_PRIO	= 1 << 8,
 };
 
 /*
@@ -46,6 +46,11 @@ struct io_u {
 	 */
 	unsigned short numberio;
 
+	/*
+	 * IO priority.
+	 */
+	unsigned short ioprio;
+
 	/*
 	 * Allocated/set buffer and length
 	 */
@@ -188,7 +193,6 @@ static inline enum fio_ddir acct_ddir(struct io_u *io_u)
 	td_flags_clear((td), &(io_u->flags), (val))
 #define io_u_set(td, io_u, val)		\
 	td_flags_set((td), &(io_u)->flags, (val))
-#define io_u_is_prio(io_u)	\
-	(io_u->flags & (unsigned int) IO_U_F_PRIORITY) != 0
+#define io_u_is_high_prio(io_u)	(io_u->flags & IO_U_F_HIGH_PRIO)
 
 #endif
diff --git a/iolog.c b/iolog.c
index cf264916..7a8b6227 100644
--- a/iolog.c
+++ b/iolog.c
@@ -733,6 +733,7 @@ void setup_log(struct io_log **log, struct log_params *p,
 	INIT_FLIST_HEAD(&l->io_logs);
 	l->log_type = p->log_type;
 	l->log_offset = p->log_offset;
+	l->log_prio = p->log_prio;
 	l->log_gz = p->log_gz;
 	l->log_gz_store = p->log_gz_store;
 	l->avg_msec = p->avg_msec;
@@ -765,6 +766,8 @@ void setup_log(struct io_log **log, struct log_params *p,
 
 	if (l->log_offset)
 		l->log_ddir_mask = LOG_OFFSET_SAMPLE_BIT;
+	if (l->log_prio)
+		l->log_ddir_mask |= LOG_PRIO_SAMPLE_BIT;
 
 	INIT_FLIST_HEAD(&l->chunk_list);
 
@@ -891,33 +894,55 @@ static void flush_hist_samples(FILE *f, int hist_coarseness, void *samples,
 void flush_samples(FILE *f, void *samples, uint64_t sample_size)
 {
 	struct io_sample *s;
-	int log_offset;
+	int log_offset, log_prio;
 	uint64_t i, nr_samples;
+	unsigned int prio_val;
+	const char *fmt;
 
 	if (!sample_size)
 		return;
 
 	s = __get_sample(samples, 0, 0);
 	log_offset = (s->__ddir & LOG_OFFSET_SAMPLE_BIT) != 0;
+	log_prio = (s->__ddir & LOG_PRIO_SAMPLE_BIT) != 0;
+
+	if (log_offset) {
+		if (log_prio)
+			fmt = "%lu, %" PRId64 ", %u, %llu, %llu, 0x%04x\n";
+		else
+			fmt = "%lu, %" PRId64 ", %u, %llu, %llu, %u\n";
+	} else {
+		if (log_prio)
+			fmt = "%lu, %" PRId64 ", %u, %llu, 0x%04x\n";
+		else
+			fmt = "%lu, %" PRId64 ", %u, %llu, %u\n";
+	}
 
 	nr_samples = sample_size / __log_entry_sz(log_offset);
 
 	for (i = 0; i < nr_samples; i++) {
 		s = __get_sample(samples, log_offset, i);
 
+		if (log_prio)
+			prio_val = s->priority;
+		else
+			prio_val = ioprio_value_is_class_rt(s->priority);
+
 		if (!log_offset) {
-			fprintf(f, "%lu, %" PRId64 ", %u, %llu, %u\n",
-					(unsigned long) s->time,
-					s->data.val,
-					io_sample_ddir(s), (unsigned long long) s->bs, s->priority_bit);
+			fprintf(f, fmt,
+				(unsigned long) s->time,
+				s->data.val,
+				io_sample_ddir(s), (unsigned long long) s->bs,
+				prio_val);
 		} else {
 			struct io_sample_offset *so = (void *) s;
 
-			fprintf(f, "%lu, %" PRId64 ", %u, %llu, %llu, %u\n",
-					(unsigned long) s->time,
-					s->data.val,
-					io_sample_ddir(s), (unsigned long long) s->bs,
-					(unsigned long long) so->offset, s->priority_bit);
+			fprintf(f, fmt,
+				(unsigned long) s->time,
+				s->data.val,
+				io_sample_ddir(s), (unsigned long long) s->bs,
+				(unsigned long long) so->offset,
+				prio_val);
 		}
 	}
 }
diff --git a/iolog.h b/iolog.h
index 9e382cc0..7d66b7c4 100644
--- a/iolog.h
+++ b/iolog.h
@@ -42,7 +42,7 @@ struct io_sample {
 	uint64_t time;
 	union io_sample_data data;
 	uint32_t __ddir;
-	uint8_t priority_bit;
+	uint16_t priority;
 	uint64_t bs;
 };
 
@@ -104,6 +104,11 @@ struct io_log {
 	 */
 	unsigned int log_offset;
 
+	/*
+	 * Log I/O priorities
+	 */
+	unsigned int log_prio;
+
 	/*
 	 * Max size of log entries before a chunk is compressed
 	 */
@@ -145,7 +150,13 @@ struct io_log {
  * If the upper bit is set, then we have the offset as well
  */
 #define LOG_OFFSET_SAMPLE_BIT	0x80000000U
-#define io_sample_ddir(io)	((io)->__ddir & ~LOG_OFFSET_SAMPLE_BIT)
+/*
+ * If the bit following the upper bit is set, then we have the priority
+ */
+#define LOG_PRIO_SAMPLE_BIT	0x40000000U
+
+#define LOG_SAMPLE_BITS		(LOG_OFFSET_SAMPLE_BIT | LOG_PRIO_SAMPLE_BIT)
+#define io_sample_ddir(io)	((io)->__ddir & ~LOG_SAMPLE_BITS)
 
 static inline void io_sample_set_ddir(struct io_log *log,
 				      struct io_sample *io,
@@ -262,6 +273,7 @@ struct log_params {
 	int hist_coarseness;
 	int log_type;
 	int log_offset;
+	int log_prio;
 	int log_gz;
 	int log_gz_store;
 	int log_compress;
diff --git a/options.c b/options.c
index 50e48815..4c370945 100644
--- a/options.c
+++ b/options.c
@@ -4292,6 +4292,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
 		.category = FIO_OPT_C_LOG,
 		.group	= FIO_OPT_G_INVALID,
 	},
+	{
+		.name	= "log_prio",
+		.lname	= "Log priority of IO",
+		.type	= FIO_OPT_BOOL,
+		.off1	= offsetof(struct thread_options, log_prio),
+		.help	= "Include priority value of IO for each log entry",
+		.def	= "0",
+		.category = FIO_OPT_C_LOG,
+		.group	= FIO_OPT_G_INVALID,
+	},
 #ifdef CONFIG_ZLIB
 	{
 		.name	= "log_compression",
diff --git a/os/os-android.h b/os/os-android.h
index 6801b8a8..022e0e92 100644
--- a/os/os-android.h
+++ b/os/os-android.h
@@ -184,6 +184,11 @@ static inline int ioprio_value(int ioprio_class, int ioprio)
 	return (ioprio_class << IOPRIO_CLASS_SHIFT) | ioprio;
 }
 
+static inline bool ioprio_value_is_class_rt(unsigned int priority)
+{
+	return (priority >> IOPRIO_CLASS_SHIFT) == IOPRIO_CLASS_RT;
+}
+
 static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio)
 {
 	return syscall(__NR_ioprio_set, which, who,
diff --git a/os/os-linux.h b/os/os-linux.h
index 87bed43b..c96f749a 100644
--- a/os/os-linux.h
+++ b/os/os-linux.h
@@ -131,6 +131,11 @@ static inline int ioprio_value(int ioprio_class, int ioprio)
 	return (ioprio_class << IOPRIO_CLASS_SHIFT) | ioprio;
 }
 
+static inline bool ioprio_value_is_class_rt(unsigned int priority)
+{
+	return (priority >> IOPRIO_CLASS_SHIFT) == IOPRIO_CLASS_RT;
+}
+
 static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio)
 {
 	return syscall(__NR_ioprio_set, which, who,
diff --git a/os/os.h b/os/os.h
index 7bf7c53c..77f7b1f5 100644
--- a/os/os.h
+++ b/os/os.h
@@ -117,6 +117,9 @@ static inline int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu_index)
 extern int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu);
 #endif
 
+#ifndef FIO_HAVE_IOPRIO_CLASS
+#define ioprio_value_is_class_rt(prio)	(false)
+#endif
 #ifndef FIO_HAVE_IOPRIO
 #define ioprio_value(prioclass, prio)	(0)
 #define ioprio_set(which, who, prioclass, prio)	(0)
diff --git a/server.h b/server.h
index c128df28..b2f6c517 100644
--- a/server.h
+++ b/server.h
@@ -48,7 +48,7 @@ struct fio_net_cmd_reply {
 };
 
 enum {
-	FIO_SERVER_VER			= 91,
+	FIO_SERVER_VER			= 92,
 
 	FIO_SERVER_MAX_FRAGMENT_PDU	= 1024,
 	FIO_SERVER_MAX_CMD_MB		= 2048,
@@ -193,6 +193,7 @@ struct cmd_iolog_pdu {
 	uint32_t log_type;
 	uint32_t compressed;
 	uint32_t log_offset;
+	uint32_t log_prio;
 	uint32_t log_hist_coarseness;
 	uint8_t name[FIO_NET_NAME_MAX];
 	struct io_sample samples[0];
diff --git a/stat.c b/stat.c
index a8a96c85..99275620 100644
--- a/stat.c
+++ b/stat.c
@@ -2860,7 +2860,8 @@ static struct io_logs *get_cur_log(struct io_log *iolog)
 
 static void __add_log_sample(struct io_log *iolog, union io_sample_data data,
 			     enum fio_ddir ddir, unsigned long long bs,
-			     unsigned long t, uint64_t offset, uint8_t priority_bit)
+			     unsigned long t, uint64_t offset,
+			     unsigned int priority)
 {
 	struct io_logs *cur_log;
 
@@ -2879,7 +2880,7 @@ static void __add_log_sample(struct io_log *iolog, union io_sample_data data,
 		s->time = t + (iolog->td ? iolog->td->unix_epoch : 0);
 		io_sample_set_ddir(iolog, s, ddir);
 		s->bs = bs;
-		s->priority_bit = priority_bit;
+		s->priority = priority;
 
 		if (iolog->log_offset) {
 			struct io_sample_offset *so = (void *) s;
@@ -2956,7 +2957,7 @@ void reset_io_stats(struct thread_data *td)
 }
 
 static void __add_stat_to_log(struct io_log *iolog, enum fio_ddir ddir,
-			      unsigned long elapsed, bool log_max, uint8_t priority_bit)
+			      unsigned long elapsed, bool log_max)
 {
 	/*
 	 * Note an entry in the log. Use the mean from the logged samples,
@@ -2971,26 +2972,26 @@ static void __add_stat_to_log(struct io_log *iolog, enum fio_ddir ddir,
 		else
 			data.val = iolog->avg_window[ddir].mean.u.f + 0.50;
 
-		__add_log_sample(iolog, data, ddir, 0, elapsed, 0, priority_bit);
+		__add_log_sample(iolog, data, ddir, 0, elapsed, 0, 0);
 	}
 
 	reset_io_stat(&iolog->avg_window[ddir]);
 }
 
 static void _add_stat_to_log(struct io_log *iolog, unsigned long elapsed,
-			     bool log_max, uint8_t priority_bit)
+			     bool log_max)
 {
 	int ddir;
 
 	for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++)
-		__add_stat_to_log(iolog, ddir, elapsed, log_max, priority_bit);
+		__add_stat_to_log(iolog, ddir, elapsed, log_max);
 }
 
 static unsigned long add_log_sample(struct thread_data *td,
 				    struct io_log *iolog,
 				    union io_sample_data data,
 				    enum fio_ddir ddir, unsigned long long bs,
-				    uint64_t offset, uint8_t priority_bit)
+				    uint64_t offset, unsigned int ioprio)
 {
 	unsigned long elapsed, this_window;
 
@@ -3003,7 +3004,8 @@ static unsigned long add_log_sample(struct thread_data *td,
 	 * If no time averaging, just add the log sample.
 	 */
 	if (!iolog->avg_msec) {
-		__add_log_sample(iolog, data, ddir, bs, elapsed, offset, priority_bit);
+		__add_log_sample(iolog, data, ddir, bs, elapsed, offset,
+				 ioprio);
 		return 0;
 	}
 
@@ -3027,7 +3029,7 @@ static unsigned long add_log_sample(struct thread_data *td,
 			return diff;
 	}
 
-	__add_stat_to_log(iolog, ddir, elapsed, td->o.log_max != 0, priority_bit);
+	__add_stat_to_log(iolog, ddir, elapsed, td->o.log_max != 0);
 
 	iolog->avg_last[ddir] = elapsed - (elapsed % iolog->avg_msec);
 
@@ -3041,19 +3043,19 @@ void finalize_logs(struct thread_data *td, bool unit_logs)
 	elapsed = mtime_since_now(&td->epoch);
 
 	if (td->clat_log && unit_logs)
-		_add_stat_to_log(td->clat_log, elapsed, td->o.log_max != 0, 0);
+		_add_stat_to_log(td->clat_log, elapsed, td->o.log_max != 0);
 	if (td->slat_log && unit_logs)
-		_add_stat_to_log(td->slat_log, elapsed, td->o.log_max != 0, 0);
+		_add_stat_to_log(td->slat_log, elapsed, td->o.log_max != 0);
 	if (td->lat_log && unit_logs)
-		_add_stat_to_log(td->lat_log, elapsed, td->o.log_max != 0, 0);
+		_add_stat_to_log(td->lat_log, elapsed, td->o.log_max != 0);
 	if (td->bw_log && (unit_logs == per_unit_log(td->bw_log)))
-		_add_stat_to_log(td->bw_log, elapsed, td->o.log_max != 0, 0);
+		_add_stat_to_log(td->bw_log, elapsed, td->o.log_max != 0);
 	if (td->iops_log && (unit_logs == per_unit_log(td->iops_log)))
-		_add_stat_to_log(td->iops_log, elapsed, td->o.log_max != 0, 0);
+		_add_stat_to_log(td->iops_log, elapsed, td->o.log_max != 0);
 }
 
-void add_agg_sample(union io_sample_data data, enum fio_ddir ddir, unsigned long long bs,
-					uint8_t priority_bit)
+void add_agg_sample(union io_sample_data data, enum fio_ddir ddir,
+		    unsigned long long bs)
 {
 	struct io_log *iolog;
 
@@ -3061,7 +3063,7 @@ void add_agg_sample(union io_sample_data data, enum fio_ddir ddir, unsigned long
 		return;
 
 	iolog = agg_io_log[ddir];
-	__add_log_sample(iolog, data, ddir, bs, mtime_since_genesis(), 0, priority_bit);
+	__add_log_sample(iolog, data, ddir, bs, mtime_since_genesis(), 0, 0);
 }
 
 void add_sync_clat_sample(struct thread_stat *ts, unsigned long long nsec)
@@ -3083,14 +3085,14 @@ static void add_lat_percentile_sample_noprio(struct thread_stat *ts,
 }
 
 static void add_lat_percentile_sample(struct thread_stat *ts,
-				unsigned long long nsec, enum fio_ddir ddir, uint8_t priority_bit,
-				enum fio_lat lat)
+				unsigned long long nsec, enum fio_ddir ddir,
+				bool high_prio, enum fio_lat lat)
 {
 	unsigned int idx = plat_val_to_idx(nsec);
 
 	add_lat_percentile_sample_noprio(ts, nsec, ddir, lat);
 
-	if (!priority_bit)
+	if (!high_prio)
 		ts->io_u_plat_low_prio[ddir][idx]++;
 	else
 		ts->io_u_plat_high_prio[ddir][idx]++;
@@ -3098,7 +3100,7 @@ static void add_lat_percentile_sample(struct thread_stat *ts,
 
 void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
 		     unsigned long long nsec, unsigned long long bs,
-		     uint64_t offset, uint8_t priority_bit)
+		     uint64_t offset, unsigned int ioprio, bool high_prio)
 {
 	const bool needs_lock = td_async_processing(td);
 	unsigned long elapsed, this_window;
@@ -3111,7 +3113,7 @@ void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
 	add_stat_sample(&ts->clat_stat[ddir], nsec);
 
 	if (!ts->lat_percentiles) {
-		if (priority_bit)
+		if (high_prio)
 			add_stat_sample(&ts->clat_high_prio_stat[ddir], nsec);
 		else
 			add_stat_sample(&ts->clat_low_prio_stat[ddir], nsec);
@@ -3119,13 +3121,13 @@ void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
 
 	if (td->clat_log)
 		add_log_sample(td, td->clat_log, sample_val(nsec), ddir, bs,
-			       offset, priority_bit);
+			       offset, ioprio);
 
 	if (ts->clat_percentiles) {
 		if (ts->lat_percentiles)
 			add_lat_percentile_sample_noprio(ts, nsec, ddir, FIO_CLAT);
 		else
-			add_lat_percentile_sample(ts, nsec, ddir, priority_bit, FIO_CLAT);
+			add_lat_percentile_sample(ts, nsec, ddir, high_prio, FIO_CLAT);
 	}
 
 	if (iolog && iolog->hist_msec) {
@@ -3154,7 +3156,7 @@ void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
 				FIO_IO_U_PLAT_NR * sizeof(uint64_t));
 			flist_add(&dst->list, &hw->list);
 			__add_log_sample(iolog, sample_plat(dst), ddir, bs,
-						elapsed, offset, priority_bit);
+					 elapsed, offset, ioprio);
 
 			/*
 			 * Update the last time we recorded as being now, minus
@@ -3171,8 +3173,8 @@ void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
 }
 
 void add_slat_sample(struct thread_data *td, enum fio_ddir ddir,
-			unsigned long long nsec, unsigned long long bs, uint64_t offset,
-			uint8_t priority_bit)
+		     unsigned long long nsec, unsigned long long bs,
+		     uint64_t offset, unsigned int ioprio)
 {
 	const bool needs_lock = td_async_processing(td);
 	struct thread_stat *ts = &td->ts;
@@ -3186,8 +3188,8 @@ void add_slat_sample(struct thread_data *td, enum fio_ddir ddir,
 	add_stat_sample(&ts->slat_stat[ddir], nsec);
 
 	if (td->slat_log)
-		add_log_sample(td, td->slat_log, sample_val(nsec), ddir, bs, offset,
-			priority_bit);
+		add_log_sample(td, td->slat_log, sample_val(nsec), ddir, bs,
+			       offset, ioprio);
 
 	if (ts->slat_percentiles)
 		add_lat_percentile_sample_noprio(ts, nsec, ddir, FIO_SLAT);
@@ -3198,7 +3200,7 @@ void add_slat_sample(struct thread_data *td, enum fio_ddir ddir,
 
 void add_lat_sample(struct thread_data *td, enum fio_ddir ddir,
 		    unsigned long long nsec, unsigned long long bs,
-		    uint64_t offset, uint8_t priority_bit)
+		    uint64_t offset, unsigned int ioprio, bool high_prio)
 {
 	const bool needs_lock = td_async_processing(td);
 	struct thread_stat *ts = &td->ts;
@@ -3213,11 +3215,11 @@ void add_lat_sample(struct thread_data *td, enum fio_ddir ddir,
 
 	if (td->lat_log)
 		add_log_sample(td, td->lat_log, sample_val(nsec), ddir, bs,
-			       offset, priority_bit);
+			       offset, ioprio);
 
 	if (ts->lat_percentiles) {
-		add_lat_percentile_sample(ts, nsec, ddir, priority_bit, FIO_LAT);
-		if (priority_bit)
+		add_lat_percentile_sample(ts, nsec, ddir, high_prio, FIO_LAT);
+		if (high_prio)
 			add_stat_sample(&ts->clat_high_prio_stat[ddir], nsec);
 		else
 			add_stat_sample(&ts->clat_low_prio_stat[ddir], nsec);
@@ -3246,7 +3248,7 @@ void add_bw_sample(struct thread_data *td, struct io_u *io_u,
 
 	if (td->bw_log)
 		add_log_sample(td, td->bw_log, sample_val(rate), io_u->ddir,
-			       bytes, io_u->offset, io_u_is_prio(io_u));
+			       bytes, io_u->offset, io_u->ioprio);
 
 	td->stat_io_bytes[io_u->ddir] = td->this_io_bytes[io_u->ddir];
 
@@ -3300,7 +3302,8 @@ static int __add_samples(struct thread_data *td, struct timespec *parent_tv,
 			if (td->o.min_bs[ddir] == td->o.max_bs[ddir])
 				bs = td->o.min_bs[ddir];
 
-			next = add_log_sample(td, log, sample_val(rate), ddir, bs, 0, 0);
+			next = add_log_sample(td, log, sample_val(rate), ddir,
+					      bs, 0, 0);
 			next_log = min(next_log, next);
 		}
 
@@ -3340,7 +3343,7 @@ void add_iops_sample(struct thread_data *td, struct io_u *io_u,
 
 	if (td->iops_log)
 		add_log_sample(td, td->iops_log, sample_val(1), io_u->ddir,
-			       bytes, io_u->offset, io_u_is_prio(io_u));
+			       bytes, io_u->offset, io_u->ioprio);
 
 	td->stat_io_blocks[io_u->ddir] = td->this_io_blocks[io_u->ddir];
 
diff --git a/stat.h b/stat.h
index d08d4dc0..a06237e7 100644
--- a/stat.h
+++ b/stat.h
@@ -341,13 +341,12 @@ extern void update_rusage_stat(struct thread_data *);
 extern void clear_rusage_stat(struct thread_data *);
 
 extern void add_lat_sample(struct thread_data *, enum fio_ddir, unsigned long long,
-				unsigned long long, uint64_t, uint8_t);
+			   unsigned long long, uint64_t, unsigned int, bool);
 extern void add_clat_sample(struct thread_data *, enum fio_ddir, unsigned long long,
-				unsigned long long, uint64_t, uint8_t);
+			    unsigned long long, uint64_t, unsigned int, bool);
 extern void add_slat_sample(struct thread_data *, enum fio_ddir, unsigned long long,
-				unsigned long long, uint64_t, uint8_t);
-extern void add_agg_sample(union io_sample_data, enum fio_ddir, unsigned long long bs,
-				uint8_t priority_bit);
+				unsigned long long, uint64_t, unsigned int);
+extern void add_agg_sample(union io_sample_data, enum fio_ddir, unsigned long long);
 extern void add_iops_sample(struct thread_data *, struct io_u *,
 				unsigned int);
 extern void add_bw_sample(struct thread_data *, struct io_u *,
diff --git a/thread_options.h b/thread_options.h
index 23c4f28c..897a43ea 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -365,6 +365,8 @@ struct thread_options {
 	unsigned int ignore_zone_limits;
 	fio_fp64_t zrt;
 	fio_fp64_t zrf;
+
+	unsigned int log_prio;
 };
 
 #define FIO_TOP_STR_MAX		256
@@ -666,6 +668,8 @@ struct thread_options_pack {
 	uint32_t zone_mode;
 	int32_t max_open_zones;
 	uint32_t ignore_zone_limits;
+
+	uint32_t log_prio;
 } __attribute__((packed));
 
 extern void convert_thread_options_to_cpu(struct thread_options *o, struct thread_options_pack *top);
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 11/11] examples: add libaio priority use examples
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
                   ` (9 preceding siblings ...)
  2021-07-06  0:17 ` [PATCH 10/11] fio: Introduce the log_prio option Damien Le Moal
@ 2021-07-06  0:17 ` Damien Le Moal
  2021-07-19  3:24 ` [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
  11 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-07-06  0:17 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

Add the example scripts aio-prio-percentage.fio and aio-prio-bssplit.fio
to illustrate the use of the cmdprio_percentage/aioprio_percentage,
aioprioclass, aioprio and aioprio_bssplit options. Also add the fiograph
output images for these example scripts.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 examples/aio-prio-bssplit.fio    |  17 +++++++++++++++++
 examples/aio-prio-bssplit.png    | Bin 0 -> 48709 bytes
 examples/aio-prio-percentage.fio |  17 +++++++++++++++++
 examples/aio-prio-percentage.png | Bin 0 -> 48752 bytes
 4 files changed, 34 insertions(+)
 create mode 100644 examples/aio-prio-bssplit.fio
 create mode 100644 examples/aio-prio-bssplit.png
 create mode 100644 examples/aio-prio-percentage.fio
 create mode 100644 examples/aio-prio-percentage.png

diff --git a/examples/aio-prio-bssplit.fio b/examples/aio-prio-bssplit.fio
new file mode 100644
index 00000000..6f45a627
--- /dev/null
+++ b/examples/aio-prio-bssplit.fio
@@ -0,0 +1,17 @@
+; Randomly read/write a block device file at queue depth 16.
+; 40 % of read IOs are 64kB and 60% are 1MB. 100% of writes are 1MB.
+; 100% of the 64kB reads are executed at the highest priority and
+; all other IOs executed without a priority set.
+[global]
+filename=/dev/sda
+direct=1
+write_lat_log=prio-run.log
+log_prio=1
+
+[randrw]
+rw=randrw
+bssplit=64k/40:1024k/60,1024k/100
+ioengine=libaio
+iodepth=16
+aioprio_bssplit=64k/100:1024k/0,1024k/0
+aioprioclass=1
diff --git a/examples/aio-prio-bssplit.png b/examples/aio-prio-bssplit.png
new file mode 100644
index 0000000000000000000000000000000000000000..7a271a149fa03762404be26faeb099f244ab7f30
GIT binary patch
literal 48709
zcmcG$by$_%*DksMk?wA3r5mKB6$I(-k}m01Iz?Ip6zK-(Zlt@rySw*Xe&@H(x36no
z*ZJo=>;2;eTs-S}<{Wd3d))Uu2>l>0jfPB&41qw<-pWWQK_GD25C}{l;&bp5l*An;
z@W1CqveFWeC+L4a8*^eIkQb1*5^q%8e(W!}>!_$cAsi2t9;NhB31qxH)HbSJZZi13
z`OYG1=j>y)*=+3NDSID&AG7P9&WiE23i5$*i4HVeUL6?CXEX3BYMMbe4-Ol>EvWqw
zsBpLL&3X;rYn={XFL@rm-|Va1(g~HLi}err_u5tZnpRBxf(rWbz-OQN_XX7`ES<K*
zzn4~vN%+4v%Ah1!WBq$sz{E2D*V~v4$|e83D-&L>>c6g6;n#!z?_DwYgxmZOstj{Q
zB_-@^xn!!Qr;~1qm7Sfu_K<P)^zPy5J6X;9S>fV<fM?bVb$C-H`qFRSz?g6ld0g%z
z2?z+>Urgyk{EBt!jVAI{ohRwAu=1k7wPWyc@$sp+xKzCKKYaMv{*g=hKiA?Wn~Hm-
z{53A_86=6__&F>b+=L}3EiJrm-KW+s2pH>C+8P=yBO{8|Q!ReYyP+YU0-s=Uu&{Po
zZqBx_$jHzjg#4d!XYcH$OW(*<kdl&?x}TX%&(3DNjitNZOtIVLQlp|8MTI^)v%Qm(
zxQtB5brbsnw)%=D-*eqDGYT~tOUQ7uuWtmokd{}o{fbz_<Lw><qOCp0ZxtI7GTshW
zG8dngmX=V^t#qD8TwHv5ditmL-DMJ=1C>^#CGC~Fni{_F<F)aL_e3rK%*@Pmr4_+o
zsz7jmzZ@Y6$#2PUd_+XVmKJ|F$`~1yD20)RpXKEo*3+dhBO@apCku(_<bQ<t`S}rF
zy<%W!+Z;#%PZb$MEp4>^H|D|xHEh1gyS~d9;<vtTvOiyoqh74@MqVC$e}8{@V<S-5
z`_^E&#h(qVY<(f!LtaG2-U}`++_`Ey0z1lQes;|d_`w(y&mmk^lc;arym_}L=yT5}
ze6x<D)99gUo6_9e+;$qaX>D;gkA*d2%t1w!uc)XPgX%X*0S5;+18!#HvetPoK_}U2
zsyH<L;qmT>gOQOj>*C^QNk1Vr_P3*#>fCIFMQndtTZUHSAM+u#x}n)hE7R=k?A5zk
zr!AgqV?NizA8j0XA}lN{#PLPpkA>Tel5>eHx>{=&>-+mU#`*_~jrCm*1&^qNY@)VL
zb;7O^5}D(6(9pD`jDKfJNlCdnbh6fMdUtsc+xT!f=ZK_kWRy`8UCz2hz^WHVL`)nu
z2Og3IJaoGCT2~|o2t$Xvuax2{Q6-kzo12^E3c@!Mms{z+z0iohnptf0#5**$wq{CU
zHxAk#5_yUX3<&sZyVSI>9Bp`ieX?2=ibLOvPA>RzuGzQQ8U%9rFY(~s{(*tc+lg1&
z1P_|Z<?&y?zCb}jim9!u3!BSPNN3U0Hy=tXDl6gO;4lHVTz<Gv-*@4>VfE?ycm+9@
z+2)4;6_rvLI0_?UAD5aMui>5BgV0u8O!b@S<$t`ib#ir0j88}iyL$!?-*ez}vMQMj
zjytnX&4<ZqyCqAJ<m6=JIjxG1F**@K9_N@Mds8LpZQf>sKQs@fiEr6e<X^fR&TBG1
zMns^VRPvkdWr$e4t75pmz7CmdzFrNtWS=nm`;~I_(XQbnXx@A*`@M3KwT0thNQjJa
zv%?@bpvX!}N~PvQ<PuU+RGgeRot>RudrV~H<Z%1uYn^f?J=)saJE!2Dqkh#+sNZcU
zJwCSov@;5?UZNMTE!-gH;851a^Bj$s=E|qV4+d;GDP(yxOBVUc{bEAhDzed0Cw^~o
zf*qAykT4jX3>G4nCP?J8+5e_5fqA6P+3I|E0tM_`Y`E-1`S*@djgSBC%;{eYIIRE0
z0*8}WQc{vTq2Rzt)a_6SURGANb_i_9ubiCV)6-K+(+S1O#onX%&h6#ppN<b`8-$zv
z$zSfSj@IVvnkBWgh!2;VqtCX6*6wf4rpt^G5|}hUhlC*3)Yavys>Ny$hu`vnusaV(
zD~5YPWx0*dtVQFKXFHaS=CVKSzr1V^5D=iE9aze9czC$F2Li3n8=r!L)n}wg=dz%r
zNlZpYrZU}Z;QK3UY91c79Zv!Rg348!zuhllWR5}pq~_+vLqbC0bJ-{4v7UxtU|>K*
zrKFx$S<hs+XudZZNvK}(A$fd!JifZ>24CKdU;NkBIFW+Po-e7UmT-N$k*MFb-V+N0
zp;t&#*_mwZ?TV&|29E$~3z<pgG(R4dWqrdCZ!}YGYV_L5%Ic)57@dqiccN=|q5umM
z69N`YLQ--CTpdS5*|hew%Mo?S_eqF}nVH>jUB=DLt);zPyrHvXwIMSrD^C}!374Un
z8C{dSf`YonW?LXiNJPXl$o0*Q#k?B)`#~}+EDLB}S7Zj89zfx94Ffp_nSbqX4E0M^
zR%s6pejQz1ECPZYM_rH<x+r|_{W;ACMH%ATmX;`N=BhdyJ+Hog|Bft57&ud5fm2vi
z#2q#@Jd6p}_xSw0Ba(!-!(H)x3QuQ-WH?v;A4+m@4GqGkr$<jhV&b-$86tUk`M>@B
zaRL<J5GjMqSN1UjWT+ai8xDxU!|es1(<Um24)EZ9fhYu)I(F}O*Ps~=ry=qy$mZa!
zoiz??V0T``_Fxhbg?{^nO)Bg~7!?&|IbmvK^x3#O%J5{h^W$hHQg3fB^c~~lDl#<K
z=le4_t*xzysHo$7i_UwKhWpcHU}11^zOd-lEq8?C*gHCo)+`3OppNAzbf?%gA)%n4
zfb)Z3XlQ73y1u&`2A(MtML$;=y1*w(Pmcs-0xr)Wafyj*V2u&c&?G;7s_1f_%oc_&
zu@GfUj|qn^!W)TkLK9O{N?~DgH8r*4lM{als@9FZ#FOI{afsiaKb%@s)<~inI?Eus
zSDO~<U4v_DYjwOil2JkKkOJi?A|e7*3wV$iE7!up!o*T|Y&x!{igm^7T@LJz7KJ)G
zJAYY>WglN&Cd^64U+<m~##O40v8zN;GBcy~^z=aY^lWorWpgvzVWw_hLG_l6g$3Qh
z!r~<(BOHY9_3PH|ZUjGj5<?#!VMxos0Gghj-l`8s4w9f$K|uM&D$=gT7YUDw!nX^r
zsI0_`t;_dTB-n}y35i2C0&ryf?<-k!8P0tL5bxA)pt}Tp{de@DPEA8)xjsKXkBN;<
z)pT`!K5obrNpS~C^e*z&|ATQRga-cug`WQpKq0pOT<m`gS5f7&P*cO*+}zZme+dcM
zuH9T-hJXl(yxRKvAN=+I!-tMWe#1txUE&dQsS-v;zOLq_qO!cE!6qs!>|NQ_dQOn2
zBtugdm1_n~w`tTE6uX8`KC+}jmQmpZ?_b3894{#WxcE*(JMp*ckyr$2a&(h7%FmLL
zy^wrkuyyC8FB!fW%<*Vj&zZpq2@yR<V`%9JP5wAn1<sRFQcB_;zXTOkhE{wc9Jn+!
z`v_(tYsw40Y1F6NMC$qZcV%u4JkL>I4m*c9(r_fpW$(QJ8?Oh_<LTMiUS{!c>47pY
zcjfiX-IY|=Luxj*#2!3wGB~ku&`t(;UHI%<U|AbgLQMP0mk;%{=$!@l_*&Z9#KsoB
zxWx)%jc~rBgHtQ6Xcsu*TkRwWx8K*m&Q|bkkpS>G?bYF7mPR8#T)k_~3ju8k<F1<J
zeNAQEV0ga*ENm>HSaP9n%L}e#Cl6OV8f8>C`aa2_+3&OJ(82G@Sk*au1~hsq59cUQ
zX3IObl{9PZ@Y6uU&toz!5e@~P?}gwzu7FEshUb-Z9eQX;NUk0sNnfdl^K(I=gX0nD
z0RuC&s6_qZl(|#xR)8_LiT-$0l0}hmwqG7t$W=h2gE|J{w7LF5ME^5}NJVhCED^u!
z<iL^mqLhrpIqGZ24pQyv+10b5qt>AknW+^_0E+vADa_Wg5|P=RvZ=`hhX?A8|LrN3
zq$IZ2rKWPjttEL^M9-KrAJ|a-tQ>?wy;LM2A%g*8?S+n?v1*|qxr5$!Ma<;F<L&o1
zGj-^J;I`kCmcH!%3_mmdr<=IimT1EB?%y?Gz-F%0A6c_`UV2Z@IZeFD2s&Jg7741Z
z=51(f#3Cfj-Lnr#v-mB&^$Roug}PSiM>d?$<$1opWCuQ!2o}!CnG6{VOYsX;3}h@@
zs3jC<Q%0d==>jGh9A_c8D01%ZpKsv34A`--Vqm{K$7|`xByDZoyqIMHXg))#xJKi%
zY@!_4fM3Pplpv(PqN15@&-_6&G|c|bdstWo5lv08D{Qng_CADsvOS!yUDe5*`D0EE
zAPz`q;?=eb%LfOM^Yc1h4;NEL$zkc22Xn^5Ki_DSn;?Dr_RX@0mzS4-!uuSn&h;n?
zpnBuB03<{dl!B@yP@~wKcU3;^Ph+JDxONE~HGGMS!;M_iuXicBz6n6W>3Dc2D?3uG
zE8yno*$(ofySsuKO)8Jg_nM(P=e@M@;80>#{Usv_>8T?sBIueD*Y?Y;%uve9oAO5m
z<QlpkFT+5KJm`W}K`X?az|6oPCME{!a<mwUMJ@G$f#IFSOhbd9ToN0M=jDFu!`)R(
zVq$PO0qg1j?@|ZIxE+oFAa{UUu|HjZi;Ii<f|V6RI*POvAfTAEv|`2kMvn_@k?4pB
z3B{OW!A3^);^h(Qm0v|ldAOh(oX}HWNZ)o}Tc^SEHJ>DaCe%nB@J5B&yjNRRSgQEs
z<meO>6!&LCA|aunZvdVyEG#Sq9aKkGSC|M`**4I{fbF4xh#DGFsugKvRV)G!@KZTQ
z9tsfAN%<h2o}Lgfqd!ht@(@2cx^__PJD&ZWn<MdkxFBHBYY3Ur_a*C&A{%@8XuD7s
zdJrEUzp~mH4*6iCQnc!AVnTzA5~v-)%*;GeW-J|l7rm`%3=UOW+wFT_Xxq!}$dP=k
zA1YDpfXU5ORaK=?@4_r7Bm^+yJ!AB*Uz7k&`|~ckiO)lyM6>frN0rNB^cjGp;<0q^
zhqK?4oFB}o-|vH6hxh@=0Lri4{A2plJ%X^XaA{T5zbyxkWkKq@F_H%WaqUx;&79hy
z_XbTN=mmzSN|u^;aky!)dt#T8F9QE{*g~;h-rk0mTHYM@00EU6bs|TQzQzXe6BHed
z0nQD(%`8`$oT4HYNPc*ebKo8biG-4`0DPcqDkhYCCnNK9E{6&!pEM==L|wkBt*z~Y
zj!p#FI0)vZ7mTQi3NE>z+lxf&6MV6ZTlHp?0njRAP2kAN_F2w3Iytd>oPUhpl#7pl
zm4=}Cx)%1sTJFr)2V9XCH1DxPp8>o8`uXmjSbEU?!)j}5pYKg!6c-oQcwVu{rwNAk
zC9;O!T^ufGGdf_$I6|>0RmN5qXw5n$WEB)J0B~h4)^CoQp4I@}?XSVvlk@X9Pv5mJ
zwAw3PyT$PuTYx_*EXJPuu_-|NG>9L$kcTK$Ov}&^2Bg%q4<DC+01g5w{PON@zC(&c
zCegndem>8}=H{pzEkWg9S;>8Ver|uUt6HdAUo|*uF;$$Z(*`;WeM)|QVt{$3YaFPJ
zjEvIqAA5hRfM-E?(cc66f=)YrZaEh}#`a%r&DfGE(Q8~+!}!5w2n%-OWVfIsLpG7c
zc`_<3ja>NY-U)Q=a1hWAM*8_dpiPd*(>>>Nbkb{;3&!uhsxc<2G`f}X^i&7X>L(#F
zghoO_vOimi0-&fkXsiqYeuO3w5J#Zz&mF6RW)30G%bx%av2k*K2@HgPjzJ#r^XCgb
zetu!qg@rojSZ%@I0DgTO$$*EnEH3KVs=U|N*EfWfl9;8Bd8IuS7ZUP`j+$D0=iNtD
zGJX^P*G{CEBqTW-xd0;(v%dGy=jY>7(Z-cVd-HEoz`p#CP(lBnP$Z^{$1bY%sF{A3
zKZ5^+i7cEdEUILeCr>5Fc`w8M*ub%|Q&i%d>EAjL&sDraZhlJ3++*AA`16S=>?MCw
z{v1HpWwr~<MYP&O9uzoOs-{2pAfV=)eCICU-am+RCX-5aONf$Gz3}cIGN!;8Ig5lI
zBMa-zeziLEUxR|O-5L3}!kb%V(V^QnT~N}CtIFL875pmL)<eg+EG44Bw8r41BpsQo
zjgKR3$c-M{U&_jw+B}N&ef|0poxY~)KSw~oIX~F*qkA8*u{&48POPVgPsrW|@8ICh
z=gp5pOS`c>KZCwd$E~Pg_vQ`J=PzSlziT~{mR3e3UVjFj^<Zvo_}3S-`v<ak^6+e%
zd`CgF!16QomC2%DM2zO(Q^%j$)pXm_BWi}VKYkef5J?Zr%!DN*-2SD?$Osw=)Z1I^
z_*vyE4@xRaCTQ9Mt7;P_c6V9jsGnwRe8%Qv#)pl4y3xzemjrqn^6k-1`T2x+)rhOb
za8ZqEq1y87?B^PF6>wcqc)LYOvRw8*ag>yh%N#e*{+cNCMpGO`4T&64sdraeU9lTW
z@f|LB(%Al~=50OQNQJI_!(&~dPPyuZ2A75M#9Cg@<HOq;&+5`iM?5-(%g;qcF})j%
z%AXz?3U%D!w5vM)+K_Pf;^})&sIr9Ko{tqwHwwUjC2}+s5@ag1(N=Kt&>Ejk<DWvo
zQZ$BgXCb>Foe^cf7YL7w6XUY84QlcxGx(Sr%xTVnMUWW0GuD25wFGBiX9o+G5`1TW
zFza1Yll0rw&Qn91gp!?|qB|-JG-G|omsMgp@(NPQ#X3E$Cu=*~b5mH%+FDf9Ygp)H
z@4D=oX^lD%)f=vjI6+H1+5AXLqm`D1zdg}Mu9SyLuV7{{k|AqJ7MpKl=_nYszmy*E
z$NXqQBfH!WVjdaGY|5hB+gfI90j>%Iu1d*VgeV=AxeQhg5FfBdO><gIp1Ue^`v>nw
zYX30*NF4xqmnAC1`?yu|8T^InY}9`}amT+W?)Qg#CG+-`L?VmJ^-hi+8#kUU93x|_
z;bH?Ksql}_y7ky>c6ubFLf^xzrViIO5_L-*O?hiazJc$I_oqMHUmG(u-DKC-2no~^
zrtsbwE{oDTXdf+JYSbK4$^Vccz)6Qg_!g6VgXn$BXRxOxLP(4peuR$~zY@ti_(Gsw
zW5Zaf^8NcL>6nq<3&Ta)%JFM|{uJEJ;W#;lolL0fvYSPu)G%|5lB{*3bhB9{M7w$Q
zB{&BpCepUGAAu*wl#<$TTM5km+v^bkj)?t}Pw1%0ht$2mkX&|XvnJuZIhth+X_>FJ
z>0lj%7#O^0{S4p4=fww4z=~`-_@f6<xyeKZeF=nr$(Mf9$HIWZqNWy9<8siX^U&19
z<M<W>a-!DK-%nqSqSy2T4&rvTFlm$lk63*+@O|S;^%A=BO_GX@a_pL-$@#}>t-g;b
z!NGw#AUTo=%o+{9pa+W>HdpO5Qdh|hS?-O$bK5K8e90L5Dj#`frt@7avvV;4RYq3`
zG*wI_2V=-WAhx#n6T(i;+`$sCpgzX+^k6;S?UlHy6fgDkRLt^l{-OU(sk&zG!c(BO
z*x9MGaXD@Q{rF7bE$dfnt4fVakQGu`QCr(rkQajY<Z4BAFx1pSsHEG7uC7ktSwR(B
z9?wJ7Y5MWy)Uop|;m^ejG0?L^iTMnEV;g3#9ffzj!372P1ef)$C@*4RczC27P4zto
zaNd7^nHFnol#yd!pYM>FiK~`!6#GNxr($Y;)lEhB80MxmEj^?B<>4aU?I2(xAeh+S
z&>_>MEAZz>tRlCrdy`+Z<`lP}xg!FaI}}rQMzfGE58rp(UMPZ0fu5b+Rzd_$)<l6F
zETql_FG22T=Fh9opAP{SV|ZyzvAxs7isN&%NS&F5XMrodHRy8va3x_qPZ-IpeGhha
zTvvywsH#m*H?LsL0@11JaK5Lz$@{J9ru9O%$Wvx3xF>L2U?4QuD}>BUs2i6UAmy!f
zk6GDB{~rOfk(gTMV2sP6^S5jGSF2+|UuV~5>+CF|zkeD8lvx7nCGub)&qJ_^at+rR
zLf^UA#lUJqKkepBGl{2&7O?#87s8zmHOnb>wksW>pHL~t@7=iD9DfKV`?ra`f{0S(
zWnptqOq_59yw-Mc>AGJ25`Mi`Vp3sg8aS?E$Snp|p?dKYpP+ktUQ;9CLH`N4d-&IY
zp_Nqxh$SrI?=S)a)F!4A4Va<-{VYf1<-q{rN%ExjZM_R^NczlN3dq6)9dozm7qr)p
zcLXQtPdXhSA0Z;wQL86@`4TD>iVsOjAu;H~7wJ#J3c9`)?C9QtfqduYY+da<I03%`
zTEFUM*h+W7iy~P9fr^iYp+(xpn8e>HZ7D!*{bP0$aukee0lGt%R)4r2MC5n4)zKtd
zFtW06_s8Pakq5a>jhI;6QqZ13#`up}Wl&?|y^ZzaVgjF++Y501B;@2+GL?uL8kk0M
zqJ<(NFE)B-XNgzl>^!MhSTG1!OsMH|p1HV49Uqs9R@=Vsz`})t6Y5VMd#<N9L7<d-
z-9I;{Wb4@-RfUL79<jX41!ALhWCRxufq&)tgbOl3(3I=J^t~c)_hkEXh7%x)q6t?%
zue7H+JbLl;_L*+aR))5j2NY?Jk@@@U)%ZNX&|v?xQWvPOvkM=~;RIkd1k~F2Dui5D
z=yUL3Yj)07NJxwun3$Nn5E0SODi222G#DgB0F8vj>-;WS9v+OrK{H3$u%%}G&qz4(
zRKmg-2pE?HiLCTMs!FG8W+fvfH850sh_+=w_Q;PZnkZ1GW|F%wkH^Fkk_F0CC=iSG
z_)(QsLEKo+V1FUdw|-7Q;ACQg3nB?s&`aZUnotV+2mnq+p7|z>OiZXND=WumX9Wdr
z0AU3JY_A(ETKREi6uGlgiIhK%s=CqJQ@c=W;=QyYpcT*7^R}!3t3&znWiE>mIE!3e
zkt8{Ln7R1gcl^u!$%cq1^}*oa1JVRRU*D?XSZs`6KNN6WGFU8M-v9{7#K<U)N;Il7
zWr&G2;*@_WJp;w<01C`P4>k1l-{iaHAIwV0K)Jd00PJIukZ0B5XA4nsVXqLy-%_DR
zfYl3^PvzfX`zQ8UA|_eK^oog#cTUOCrM+Zkj^9f`z#!jdBZmI7<x4jb%72%S!T*23
z9^e<WE|y#2_7@vTz+V0R``53mj2$3lc8gIO(C#X(2<OPBwgHSA^X(ffAhY{_yv89X
zC+8jvSISAv%%qV^=8*Jy0%U-gzCOj?WKsJ-3h&DLdO)JS4^c_O>AT8lXg87WbNiNs
z$J~4?=YTF_t8F~bd}YJbKU#SA=iUd%N0GGAQOAapE}~C+lh4k!?kuw+>#}ndh-clE
zH(S48@6RO$$R?I6>ga$L)JpEhHVgs5AL6Teuh$6rzTR+<QhP(~Plwj@KG{33z0PIA
z0I*=QPU3`x6M}&xCr8`gyYY*OkDVMFzLJXi)Y%bA{%-H<JJacER;(O(Q!3UH+`~is
zB(_#Kn^}#ix9+ADMCLv|L{a4LJL4H&%gD0?l$DXsR#mnZl+?9@0x~(hyQfpeN}{LF
z14uL(D<B<(yi(3yetfudoWmgH^TT6QTmFI}+!BVzxGt<+W&|$`4sxxH$m2CNkIii6
zC%w4310az0PB`CRJ1}XKiWUz-Id#yLbaqqtGTGjp_OX_I9H9y<!%{q;qAEY$j!~I1
z45=VfaIZz(8ZrlI_=A<rIJcyC#>ct!o}7{FNN#*qTmAHvSI&nz_>1maq(IHWstydu
zGzPrf{fV?lmi~TkuZc#(HHVS06J;#S)e%9Tck#|^LC;I_wzfmVt_U@V-;i*97=X7g
zVufBQ-}Kq2g6MC!nA8Lqmey9lnE|KXmENE;tk`V>Zz_kOB!XuxBBK9|!LkJ|L7%?t
z(|v4Ek+z-jz;|0hzTvkP+855n(}`#$tRw<-+L?GUF)?nSbyHNLx?lAK<O{pcy<28x
zra{j)+P}TMZR+~o@apR74yx@yK<K6A1l?8p`OX*?1w}MG3jVmJfa*XpCjyXkq(Q`&
z8MZ%vhJXMEX}VrT=}+Os;Njun^SorjXVqgm<OBi-xNGeir!910P!)2H*fO?SFhm*<
zQNn{_-MA{;h#4dwK0SKj(_oXqt4Jy-!7TdRF@=R?y6w<<Mvxx_WxtQaB1s8O_l*K#
zck-xrwQb}ZDJiTVG^eg#;;)?Xm6xsJ75?J|u(v1f?>}GJn!<&AP1cMs8;~0=NvD>3
ze^KV`sS|luqE8Wcw)JOu`(v2vk_{R?z48yf82?m(wNkeeT96rV07lMs_)o~8qS1m@
zgp7=Tx@Bet_4RAo>y5-`5>lH6t)Ef&+#PdAS+D=C>i01<eI6GOdyHy@8kBURKm%z9
zyhZ0wL}Vm8V5uN2=IP!+u8ZynpwCa?wF}xmN%zyy(K!aHXxs3I>tHd^z=OpsiFL{U
z{@RI7_~Bd`;#X3_>gDAHfdKV8Bq~ZOnp|kz2ndw`0NjC8h5=z?V{55DYAUc$#}eYL
zbG6Ig!(4|hXMWJ4g1)yioTQ{u1j&{^YtuH9?GXUtvGkt5GBb5nd|VILjX}T5q&thn
z&W^FiM4l{1sJb`SjTIEsHh%qd*L?YLvi})2lKr*4Wu$&XU$4n@B_j-Il<v>RWI-E;
z4H?dfhNHn=&PiV_wVEPh(pWA~y!rl-b5K5Y-~Mpko{(g(Z{qB<kHu{x9#cYkYqc$q
z>HJ9FTOzw@5bsXOX?DM_D+<Nrt6D%{U}(wO>gw{*5$j{2ezV>^laLUZgF~B$DA1^}
ztFM62Emr|C0OG0hq`WE&49uz(V6AG0%FE01J2$~^(P=^03|b(87uZ4=py-13u*_PM
z2HNltakiC$E{uj|U7b<Dc~_H3-=}i+vZDhQv{E>nW&y^t6@RYx{}j|X%Rb7AT3Eb>
zg;OxR*iCu)>Q(pUfy4Dxb33$Qs{+wx_)Ep&rksPw=Z2R2k9m5xRY@wgU8v`GxAClZ
z{eEoS#%o<4`%_8$Eyf0oc1C6H&lJAT7s=!&C|3`~<;^RMjMO5c3c>>fv^PcZg6%l&
z`mDk`Gjx7l3A~d*PVT(yqhh^f`re+bfn|P)fx`0d=;EKs^x9zeie2hCh)NB`aly?2
z`4D?UxZdYMn1hqzm#?q1LrP;~XfL&YOw8-Q1I(S_tUNf)Kh@mM-rGT1dSZ8o6A}D=
z{*-w3Jgse|J<oBjk|?LP_D$tF1cHioal9JdcBGdq=dcDMm}^JYbUM*_Dlw8w8U!&i
z3QFhH+qZ9J-n~=O;-RNUfP7F<0bOfF+!Mv0-Mbu%oP40RhL)hAu0JK_5)J@9EHE(e
zT^W`T2J|*pJFRPNx}$T}f+>tZYCv)H)l}uW+B#}hX7hc7k4q3H@<v1(Xi*U9H17F^
zo+LPf(h~dn89sgxw2=VZWDltyfUu=@`q-EIJ8;_C)PWoAZHJ*7APyDCqWOFKekt{{
zv)2-e2;<(|oK`nJoXQGzMZ0!yrMoH?{HXKJmfP^@?PJ8-(qG?9=pE<;Yg1H~HYCyv
zmS5EueWf>E*Q&8|dw1dv6rJq_?Q7S20BR{YPKEmi(3U~wC~4Y7$BEt5fA{6{;qvJQ
z>HUSeZ>3!@6HCJC7Yvq_;a?^VceYj$6s%8K+<bgw9v;}&cLKTUC&p!E?hwByvVx%_
z2WRdtk&#%dYiHan7!cPZd>{@op%Q0$=_%-TYsP|Bvwd2FLbqP6q(FE`RhK-Le>!o9
z2b!2cDF@o>Ge`sxXLi@zzE-s@8pPh&SrSmskdUV$d*H+1x01#Iehwo!Rq4M*#>U*m
ziMeHcL#&;-ipATDjjwcc`ay-lt+o~F0CB8QwV&TMr@>%iBG}dzNT8^t74=IzmHpF4
zCqm*~N-i$4H*Z3(0h0h=Ba)YQI+LyasR=)TU?;5zHY4R(c%!3XfLK6XT|F)Jx>1FK
zuHwkBQxyE`jQ1oYNlDv`WIMw&<f^&EXK6yNP(B9)X2WS1qqTL!*B?3|0C9dzyrL;n
zs{E1dt%gHE!FYcvYZr)OGG0}up)xLByI#m6DOnlakd=eti|FLY0i@wyA>n;EB6oL3
zxcjs5e)>K;Xe250NT%}g>}rKIfPT|zZ*R}gO6Bh9W$0>t#0$#J)hPsMms+Yug%OAJ
zN6=vEfq}Vsq1pl-13n{2WfCh}mzQ)Qp*@m-3z2(|HV(FAt=n@sD{+72(6(4H;(JG4
ze@XLVYaq%@lE{+!p&-nKZ}IMK(s*Z+SJhaI`Q5gRIaCV(DH;v};M~cGG{rBcE&8j`
zt*x!K<<>7U^728=%_0zkju0$9_fs0k^7hDYKo5#u9WI<~k5GF(-fRJelMWUZ)_!;V
z6{H1_nqNR=1)`X~go6Wn6IhhUJzC3spPMY+!PGvnk01G?NZ-DB`}Va7N6WMZ#;aF>
zG77ApfB#-J4SBkzMv5j^O}FASk#XXCoxB2V$)@y=3}(vdqwT)-_>l>C^w0{n2fYST
zitq81eh=8+K{n2@M8;+(bJq9-qRD?7_Q&7<IA=4SvA)+^@jKs$xb3*igyU{i39_uL
z`1$q-E;f>Z4ReFqM26&n71=|6q5IivVo7mQ^hGzt+tPB54rvN!znmQSZ{LthZRTu1
znm4*REzqbveJfV$b;AvAZ1td8JD(Kg#k|;SZx6z-@GMY17q`cIs<e{N&#C6?E-+CD
zs#FUOdo!b*<h;E*#WC>a7^OZ=Fk?ViSj;L}LiMK{7#smuOkipJOey|-ZRyEY_2BGQ
zSl!t{?z@4$@Em~GQkRDd;ediynLFIv3<7$-!R7u8pZzj)pJGx|BY`#GC-4dY#X#!a
zJLJ*P(HHUW*iHUoI%KtK{xJg@T9de(94cT!p&pK3z#Jj-_AM~RggrS7XOg|||IUpv
zS7jrvqeGgh^y>EVAl&6(mJ%3B78e(Zr)0;I-ez$$T<JZNPwiFFqGK&lu_(vGqwPOQ
z<}16M_kSBJ2vpK)`@MvF8*>0=)k!qVE4kZR{N<<Xd9ljMYPW}1dJ_F7i;7fz(!%LZ
za>XW+=-;1q01_~Xof@^IVKvC*z<PPj7~a^}yH>SRg*nIeZZ<n|Yd0wcMc??{yWTRe
zp>FO%wMF&%BGRZtj;O&HIjiBUy@r6}14r)!Z2olhkp51hsAR@(3Zwh$4`5%6t_~ON
zUDST$K10ZXfjmbYzP}XY<XlOLE6UI)Ys~mjx3SkdR^@qYz=6+H<M;TGdOX0(DypFH
z=(W8Hfc6G=SCe%}+5<IB5p=EIy}Q^DV^llk<l*TW`7K=rR2A!)a`?QwypXUk?7o@l
zY3QkNI~(Bbv;lT7M0E5n61xWfweINO6&1JuhZ6GIl0q#%yhf&GX4wt`-%BehKuh0!
z0^SF8bpV$GjxiL2uWV#J3ZiFp9k%$J{NRsA0_+c<PYLE127p-x5-RbTOkmZ1UB<F9
zkc@$m1z(ER+B$#9*3`xZF?9WHGIDPMM^zP1T)`jcG1Au9Wq@X_KOlmm$VdX79$1OY
zhZfs0L^`OrD=`~AX4bx7%(jA7ya;+GY-W@GsGe*LwYQ70jKBtrkbp!6OnelYnw|C_
zXMN}9H8jeI27sMTorj(M$svXJWWlveqoGD<w(<{_2rt)oa8uK>+S)8`7Fr6@AL#1p
ze=N5|$?&K>Tn|;!hm>@fBrPo|NlE28SO<0!N*EQ!4q2N!jAzOV2nB0iPZl4rL`|w?
zhdXsPS>JolU;=6@9=PVlwX&&@U?J4h)J&S?&twyr-WVBCDJd%(T3e%<o10J1%`xf(
zEp&Fm1J?{F=3?Lg%r7jAG`KtMFVw3uQOC%ve<N|8b8vEs6~I?eP&lasyEborFjrkt
zr9UwZ1k{boo$);7q6eTOghb%tr_PlAlCD$?=eDw)tZQy;{EDdC=+QhoA7eE|E=mVS
zO1duHX=LOGiVO=&o^Gumgpcnpy?WSVYF?k4$}jo;$w?_t?`3sDs5#HD9v_bE<&qtV
zDJj2n;{E*>+q=21V$>u^oT|LMZ468@gYT|nKj^W<-i0^G(e-n~yjY~u)OaZg?E?6~
z$G|`^C=&kKT%DG;++MIQ5AY5djAkldAJ(T$kblrtp^<dE7HYVh9eX$_GKyp8;(}Ak
zlRNC&&QneXbY)MZM80-Y@yFT2uE-IMKbs&o>i~ZMZ<c<QvjgaqBAZ!Bs6at3&q+R8
zKRiTty_!uVdiXCpE|RaWZ%u723<RiM$G%TjzDCLZa0nR|%AIG=R4lrI^>n9fdv9;b
z<A<%St&ugv;N!<@6>srz4b^^vx=*jP<*GpQHw_dSKn6`!FhW+`8AYB*qf45b{MCvI
zq30a}2<(p0EOqk4yj#8?Bd^;XRj+eJ1VW;nH*|1ScG2yCm$P@`3{FYe#ChZnmB!2O
zYVh_X)vB)goW2x`r(|OjX<%sR*WWK)<CFst7FJ_ORIc`R2E^El*R?;jJ}cwc^v`f`
zj&=LN$X|m(3&q4o%||HS-besN^H_(7fpGNlDg+fkr+`uIlVVcG!8}oPd$4k;!5e6A
z9}JRKe*DQv8Sq|Qw#L26VK?oyuwL8`)@w}D!2oUiPta=E_PD+W`6dI<Y&vyuUjPeg
z)cU#Vt4sjA4ybti5QB9Y^~k;{Jm<Oi9zOuk!YF(r+5w8W-YqERj<WohZAg6ec_iej
za^E1Kp>={-G&DB;0<r~EOg}j}dC7<qRB~`|Q0A~EMJD}L0s=Y-zetkbWuGi)nx2I5
zflgfGL{Cv$OZ#zd@;R^VxL2P>vrp9VnN`s7u_xi{Q$9gKCa54%QzICcknr17mN9~i
z@u@o&pP8x5)s70CTrMa$7#@HiVAP_9w0wsD&id}Bg<$>%?#<!hPoSs3+uVE(-HDhO
zVSx6&CaNO?#LE5(;GMdIg7&GY=PN5$%SXPrfI|B!<3}sYKhDQ03nCn{LMWd;*ipUI
zWpK18QB(Jwnl=jp(#cnu7rYkwGy0=XH_~p4Dg|l@+$^^%n`Ti<K6~NSi~L^znNn)0
z%8N>Ih$^b_vt@Mj!;1J%ak0@do0QUgTlpxq*~{jqh0cw>w(aBP)`64F6y}ao3ZH3m
ze}DQiXDigl`!g1hXfW~O!&i-70sH4?fCo2r)vLWee4x5KQfP~N#mx5U<C#b3+20sk
zpoWmrV87t5M2w|RFP>D0UmKaIHPYWLW=&W1%4O$%2~5sBL1-jFz{H``;HId<)IK_j
z4NL}rt5J_*Nq8f1QD7`B0D4WB?Ce{acMPH?Cg?QSP~PJBtiU^-KlIsj-GqXi0RWho
zco&#JE&77M+dU+5m46vQqo9CNsC@+sxZWC%3t^z0Jp<Up>(QOyB(XW0>tER4Piikh
znF3t=1gPd00w@qYy;neK2h@o^c4DFWzl|_nX{&-ZwRw5KRP(nDoF2<atqEFCK^!`J
zfG!A{`WK7^ge)wZ(-l1!kB<txqbl)@jYuvByOE#-1HtIo<$f)Y7l_2fMggt+rR_E6
z)gj*6z5B0phBT451T`Al0{)UL5b4%4tHGNC17Fkh0{;HJ1EgQ~SIU7h({TMtbDBKu
zrq$Ql78ZffZp^%MUNjkXm0S5D$5K#1HWnmzl|td$Q%%~Kp7F-L+fawKE*Qw?&!2ah
zUQj_^zI-X_<s}H52_u<rae%2sTp`+*<Y$oh+|#2el)2TfL=Yzb-}1D&ry=u81_p64
zF+l&e%*|m31$jVMUrP&%|5GVm^S!hLBF3~TSDWI84^WakE)hjPtw5MMyGA3d%H}E9
zA1<}jG@Rm{Y@frO3pt>bKTh-_OG%wR3CAV&VPeIgfhe!ARDGCC%88W5Q#H<I-b4-z
zRHC8V6sN<n?Nq!RUYYI9n=|jdmCzIcAgQBklajX@cVmO2!os-d6MNLH<CQHXbVo@@
z#DQv=e{agdUIy9Okvu*r`zA2Ott%}lX$p27+&-mZI@b=aTFGJd@nkMYX)-b&9-saI
zuD{KkqQ^vRG#zvu1O%L1Hd<$Y>Q$K2LE8b;&YJp^z9Rhm0lq)wVH;^*vSlXRa7Qj{
zm9~-~%MVwqP;qfJTI9BenWeQ!<tS-4{69qYuf;z-3`kI^Efa=L`=Y>dRkYGLeIh-c
z(avD5YL3s>r-n}?f;hWQSpD%)dS%5h3Pf7|mu=$2F1Lj}s+rXv&`}R=xpZ>1HIBc2
zrG6b%HbQ%^s75P+q|o{E%>c;&!QhsrZdw8KS>##1dLrJQ1xz(s{$rc-R@wrs*Ec2v
zMS4b+s;kEoAMzV+skyD4-HV}2fv2loV7Ry-hTB3x5L98~cI)c84T&Tx+GB%25?P~%
zoe>!<WW1%$naazR8jvXzO?4dnKqms&?*H2`id+6`Z7?(e`j;-xqegZ06HE&lI=bh;
z;0r+5xbw^NAHZN65FQ?0+z#elGM?|}eJcV6Z0gsqiGU}k=pR8JnUO&S2zp?~K$}*k
z)%Nje6UV;!U_8nV5Sjbgrs2SMZs280!@<MgrUMJ36yyYy6X@%|&AmYR?+lNTriUj?
zLbrE-T-{|%3v!viU<NURfI+v`cttgw)%V8D^Qe1De`(lRLqg(WHE;7DJwIX6^NkUz
zHR%Swk;ue>>N2@{I`uqCQ<Q%#KAs2`6c(Ye8wH@;UbzCN6)q^(iOyu$Sc;8?{~RP*
zXFc?(9a8`}@3LW2W!!eZ)<)~^jb{Y&BKE5tNRgLM$L$!<Z#H`4>(C-{+j`^uBw#<f
zMXt7E1U|S&3gbX^GV^rZ&f}HVk5h-f+tVkIu1J(lAk<CtGNja>cT>2syX+%<+CCPk
zu(}e7Aay4daOwEfphK7NiY1|K&Qk;mg=pvrj5ho2KOK5ulJVbTDCeYg7HMN_>=x<>
z(`I2hZT^t1w)JfVZ$?JRQXo?Rd5o$52Vlj8&|9aj6rk9@Ky9I=J($*c(vFgHCy8T&
z>;4`c*#Djk|9&;rXu4<M;2^h90jA$w4C#N`6(GT=g@qMt=QjFY*8uJwQ1iz}zSa2-
zPpr)iQAbVn%+&{*1Hsqpu?5h7wwnBuc(=dOt|XU)$&e@tRsK*2%8&O-yaD0u9Dhnn
zD5BTYkdgT|*3IQGqMJTlLQE~M4ir}F#UBVD7H-bG<EwsKHbZIf+jF*BM_};)oxZro
zEw%OZ@n@|KOAde`eh7J%0QW-_DNzWh!Ky3@66b<O<r6J{mxrL>GYvZvO7t>oytv1N
z0hWZ0^Bv}qB5fRCSy&mNewC5o2wdHItzfJnNw|>~lnvyoMu#<+rn^HPaCm@LSkVp@
z9YMVx9!7<NDpJ0$5kUV0S~ATc4pvN{e5!Ssg)#<EEhERr#R@f@P(WOO##&~7W=y&`
zG9<(rihUwU9){~G@xUd4=Y;<RP>jZ)^&K9IHJGhPAmkk+lb6qi0=SXi7HmAlH(gk&
zcL&pDT#%Ogn<nT#1N|AC`;KJJWEnXo%su5wQXrMHLj6{mWu|@nMrWIZKqrf=sGy3A
zi|g}F`=*4*%j*<)_xMoF=4%dgW4W|_+J9;#;GUrE=i@D-Cd)rOH(4Y!k{QYl`6-Da
zTc|rn1_M)DV^2u}fW^nz@tSw;BGWTMGugl|bbqs@E0e|1|9yj+_wz(XAg$S8p?8J!
zgpboFE<9sst%NM^Sipb^Tzi_IP|y=a)~LcFD<P5ZZo6r%n$~wdrXT`>%Y}`d-M_wG
zAc0vs=+yB>|5HixBR>r`5|p5wP(7Ie_DS5yW-t|2VY@&K=90FDf5Ab$htPTkEDTQ2
zW+W*o>8I<_BFHpx1==$|it1gDjBd|&0P7VP6N5!cMh5(>A-TCPv$`7q%mY(3Egc=t
zfX7{<$?G*}+}C@7JAVZTJfa0^MFzIE=+e^C=SNEv%}<X4CL9~pvma=$4q=LmMaQy5
zmEv#k=@np~KNl_06OC^w$v)M|PWOSGt%Q@4gSfgH%y9hd1+x(P1ig$kQk_E#y1yMS
z>=scgY|)aw!;<ksqDvHUaUo7yumdS5HdlveDz#GagEMuW1WCfW+bGo3EhAWnsLw2G
zq{<wqm)EE(fbE}2U#~H}yxb2%7@}1P+dmNKad(B_^F+4Hov#e~7lZyJoar)Z^w3cF
z3GC+(w{w~NPfr4_0dw0RU*%tFK0QW39hY5GQ&Msj41|O-!+*^GbZ?v$#H-VeDDkG%
z@cr5^H5_D^&`sulxCCGbm~e?;VL!9G+CHnYsgEoz^?b=3za%~3C?TQJoK_!Gbg?%D
zs97J(C3;%g6`&JJxx2px+jlvBQKD0e-F$x<e*Flh$Ot*jP@zg87~xp$Pv%@T2Xj_k
z$1Ck%t^@%G2Pey!j)n$m9t5*dt5sm|2`X3uaTD6PgCogX>kYIJf8f0PJ5grRgDoK~
zZM-#@x_Y_N9!yO|CFZ5Cp#e4=6^!;QgAe-%yo6?CCxRA}sEEk0x92cjk#O><*xw>6
zxD48!Q6k+P@KWw5b>3cxW?A9BecRGafzqQ!rt@2)7CZM-<mxQ9K|diSyG{)z^t*El
zgKPU2Eb=lTac^ZH_xFD9re1Pz_$}1?e?b7egFnO6OSM7>*jpJHNCFc~#&3V{h9C?C
z@ROHJxVz{`SVmji`JBKm7XXeRD)~Gqa3B!_O_Gg!B3Ob-P}}0_@LBwB%*&>}57gfn
z;%BA_Ej|Rh^s0TxSpv*yDd1!}I@VX`Yndb@g*p}+L;v=?>H<YTLewuDWVyE2;GjDn
z)e_C*1NDTZP`er(wB3Kfd>a^sLj{w6Q2(a9l;h>mQZ%p;L+8OjiPot2hy|U70Yf!l
z*+_*vaDn48Bsv;&aByIjCk)J;OlfR^6BU!390~>#m%&5}^o&7`(q{dH>l+(};7m<i
z-aK3_m03<OWM*em0cszNpnOhECG&Z_G5;sw0rmh$(*8gfT?W^Jf=(9~9zdmm0;aLO
zBjlPGya^UmwZQLe%l~Q-N6MT|9#^W-<p^IYOa)9{mfDhi{f@l82`lo%L}N+9Gd>_Q
z`1sH=StMo@mx{)uMbklo`GSUBIvV+)s~ZmPIikb3W2Dic&aWn6Z$A`*0IYHn-T)dF
zRt3V7{N1aiKw;VU@Q#iFYgK=6qOMN3!^Tx8M=Zyl^SR3B@(Pe3qQQ4X!MjE7swjP9
z>pgqCYx+3WMQmm!*7iY3DeCxmwz<O74N-p_bVmi=E~^2h0}Hy3_#G*{6i}a*t+r+|
zs-dBnXRocMN+AD<3JsC(Q)-5b!1r_Q0yQ<LFp=&(NhBSG+JVB#)%h8oprFVj*YY(O
zlA#z{_&e$Qbf@2NcUZrAH>Kx^=6ipF0Hq>9@@g9xILO=82c5oIe-dSrK1frb0tw95
zyJ7%4wK!0=AdrNFglj-)jWl|?&NsL#TX@66!-Gb=+0f1|8V&)yrMDLuvb?t!uJ8MR
zm&)(l2D&Ls9Gov|MQMe%+;)qC{plk5ULwE}Ad{s89q04BI_w0IFbsNwr0?G|q@&5*
zR^Sb@7&tjOfo_Z7efw8|gC4Kpjs+9{x%KQboo1E@T<;TjAdY%m++Q_|>EeNBxL(6B
zIMQ2DYs_hoD*N>6!wzxh=|+p|5>n_&nQ_aS6>dU8OQJsPLOmR}&hM8mA&-wFrPTzs
z(q3MXZBqo-7wSN@TAA!jB3w~xK|b4ri7!@^`~FNOt7W~Xtqh$I!ev1<zdQXK;rN<3
zFgf|__zCeu?dCwByVzXSLRW*kje)Uo0B{49nGG<5nmSd^%Vw?N1g(S@d%q2BZ9@PD
z+&=u_b1XgQNe_J+Xs?6&qW|LJzdI@M4KxH=60}Fj%aeq%IiQ^c-aDMy8?9X>`ZUGg
zI%V!oTvgVg{wfUZ(`ASDpSUC~^Gij8Vq(a%<u818eY7jKu}R6^vm5x~KnX<v5w^E=
z=9^N3ffE8~C!Z@Tffe(ApIzCi`-g`Do3m4FI<c*d4b?k2UDa4zAt50!)0k0O`T?Zs
zn)-S;Oj{(CO`rq=3RC=Ov9VL4;IqF!Ob{y3XA)l97hqVCWrmo;M5eMX2%QWW5)v5+
z4*~Y)H9$(YgOuxVFw1>?clTR77=0U1a)cy#7IQpcNQQERSeW#B$alO%yp=nwd+O!x
zGI3Et=JpQKSs^k?I*k?{L-7~lV#WDd>WGMo!v~s?d;<drDiKwLV`o<{y*6^OqF|HM
z3D|_Pvag7PKVHpqY#*`qv+vDay|vEdWNqFLgHkAf{s2}s+-hwNLIYs?16rk4<XyFm
z)fbDg1~8RVrcrl}oWK(AdpR3|#X`s><MXI;b@)CeDJfcAA1!{))+{?ZOIAR5;v^R*
z8nCRu5fQ!7S7HQ=iC{~q)m<i;D6$T6$Lv7Q2TWGLGB>d$e0!_a{*QC5JD#%(1^$R{
z^Hso|Rq9+YY+llQ7#J<$Q|BZtG5$fw^=cUey4swYL$vS493rFbuYx-J=a3~EZ>s-z
z0dVo~UKQz&%rk~cWPGYG=ZTB=CdPACDQ0A2!vte>&><7K_wP@@jB4xD6alqV1h5z$
zDp%jkhlW7D#Rg7Q+gT-$z5+NPlrr9qy09ite&j;Aojc$DFkT|V>;JgmhwU+1*?^{-
z175>%>kh;f7wJ(VU@o}7cVfN1;RddAn8HHT5#U7l{P{NDOJE6TDkm3Hx+7)3nSnRK
z(7G_1$EL8%<Sm#9S}4+Tx3UrkfD_^2P5{gpK+Mc;w-@I0RyeD;e#r~kHH^RtxSWdt
z8mqL7{c~BFa6=>W$)JF663_dST>PJU%|#j`c)+xiA&#J}p+yY6LXnoH;oy%+sQv;_
zYOX4@37B%?Eze?r&VaPFVdIs+7{Y`)Z4FLnlL7@2YAwi9&iR^>!pK`k8~@JXd|MIX
zS6zM2dPyxEWdMeZ9p@e&@9ZF=;rPtpj|6CG8I9*E5^`JOLJSq7!RV{O&FKbU@k(~@
zlhQOTEZPK%%mxCmimn#n7CmH>QZmu-rcA}!VyFDr#8jiFUJ42ZU==Fo1gz(rZYQWP
z^uxgUfg&A6ie-yexDV1k_=btuU-5SUg(%_1?(mx$_-|9W@|D2RmhM~Zb2kH)6KLq3
zwKh}5kt!P9+atDwLRuGd#tZZPCkNF+R!qiVg{P-SxD)ci-8?R>>52n#<puIDfq;%=
zHgKBfkSUkySjXnmAkY=PCBua!ln#IrvudTy96sb2jNMZ+Fd%~oXy}A%R|L_QINS?*
z39H`uc~a=q0T`CkbKk(zsr!TkWbhj2J$$<N-vhvi_-{aiIaXuBwg7-r=5b+}nUk{y
zOi9y?p1dF_pg;%(T$muBt%e1@hUscM3T$j_P`5sxpMTn4YNmi-Qc&pIb<b?a$0IRf
zn3*Cm?hm9O^rxZi&(Sl%{z3y#wBf0#w829W%l@Xk^rfVb-fuQugdj8=TW+rnyya0^
z%9VO&*`#3ShdMU90sw0(t^6kn{LeovKYANtMS;9Qt`9^?O#H*?Y6Tev*>?e_;F`z8
zw9rOBf?E5X+;=V{AS$$i0cYqujzc||bp^u{Oi?c<f-9}20KjoVL_&H496%ewe@aVR
z!2C`A0Ve<(4Ns4EZch(a8&%DhvsSAii7E`8V20lwfPc$7SsLtT&!11OC<?9#-+v&S
z(JT{7Qh0_K+7XD-W-jD`I5e9t8%u{&J(>ENx^Pmxb%uyg@VX~N$y=jdjqp7R5=_3%
z@6uAt&2m+4vxu)R)oP_qW~~&Y8ZwoZhbdQb7(yj#I-vusx&Etv6R_#%==dDh5kbm@
z1*K3!Q_~Pgn^1ESm~psCh^hPFt{0z}NWh{~;|FFyTETGh^XJb?tE;<#@C1O6;sKGi
z-|^QCyQZ7x%-U4}pdSG<OeZ@z=|(_^H%cbZbAtgR^=)9Dd3k3C$=KMKPe8yJ{Ot(n
zv^fZs-xq85zL$rBEWMV#%h$p0-^9G1c>~jmM!+?XIVRzNRNY_MzhRy?!OeK&oHu`J
z=EC@v@%_NUJBO)x?zc{z-bk1;x_%OpDx!owzF>?Pm5tMH?bN$j@5*`2eelPb(AMiV
zr%m_4*F%A5BykEQ9_Jqpl~r5%<!YZ2ii%G2)Zd27ZMV<s+%V{E4ff*Q78d?=wcCIt
zQ}`L3KTvRbs)Ww;bo3PWMMznBqaYIQ`O9>9i|yZXNsuLPFlN>3-6JTpayInq14Wi3
z%7$oxo&Ls6Z+!gC)%Gu)*NV5fm|}>OX+}~vrqeq4c1ukVVCRX~7G<piGfZbUTj@^V
zZwG+cXp3$8G$JV}sR%NG1Tg$Z!XLM_wBFPEW+aBXm)?anH|+5t@!K~sGqat(95^t>
z+LOc{)zP6-{8b|WQ!Hf5U)YzGjEt-d@KM!&+1$%7aBCemkhQC<Vd7AX5l_Zz9VKfM
z@m~^jLGLC2v-4Z)q%t%c0fENh_S|B&$|n5x@87?~vBeg06_+=&=YQ7NXnz%E02fD8
zq$08wk_3OvV|${2z-qFP{nJaak7njMIu0NH>**x&Ot{-}I>2OivWRcfuXfA~x3ewA
zCwk~FQ&vzZRQ>xR05b#juYoM|<H3&^{80bzKW6$0eFN)E?aZ~$fvj|TRR7VLHB;K?
zc8V02qh$xH-M!LkSuMiWs@a;<QBWfqmKj!Fa-LVk26Yq-siMH4#a7R^M_KznE{vCd
zsHdV#?E3W}_zg{d=!;}3Tjz~IImJIRj>4L}<{q>?t}lo4`eFY({TOIyKl`xGsM7tT
z=*LaokOG&z^-on&tHDCUkuu4S#Sm{5mx7r4`iJK5hlr|;uBC`A5$&h;9!C1`b;Y4y
z<V#nN<QUq~*lV6jHYHY1U#nQtt4jXz4D&X+-TsYb1`otq;R?5yrLZP!+1(^^E<`eD
z$M!*D_i%IGbU6PF>07?fMS;xTDd(mtdy1d($3i<&LUo#*8mEU2LuOkarym;DFO_P$
zDtOIU>7?i?3Krx`IHppyyD@@&S`ewhV;Gne#EiS<4pl~2HIQBMTv5zVF+?@5K2cpt
zF_Bl1SDbuQw)D{LZFIatrZ4%?F)$lxdr^1d(pSARmW!dvs7lMh{q0Hn%y*r^F`Rkt
zZDnKegZQkTZ*;Y{WR<`0PUl#joI+I;>1#1ZM-C9A8+g%}9w=yNv|L={!-gRQAt~A?
z3OF5qj6dy-1fl<uSR%WQx=uOaa<FX!dr`_!t&}R;5Fb*TSKBqT(9_g@zA#2~I*N&V
zgDg*z{<1phQg1fAxn5*)bJ8RJ_0_V@#?w`rtbM8hMA+koS}GuNS#%!8N8o{^{W}ID
zchuwi+p{;z2yUuZM$+Txk6}**9p`m%dtl?gw_1JNoRwpaF0<(#_0+V(wxz?2!F^Mp
zRTLI?Ml+{3^+;(`(%e1QL^UUxe!jY+lHHmBh8pql@f&V;3;sP7R6v`WN(A;~B7WSH
z&tTGE$+Yw$sag4HQ>G0I-0}UwgT?B+gmGQSI%39HMo<4>$3R!)rtLskb;Z<cT|FOi
zk^2icy@^J|Jc<nGo9Gl*H*)j@^mB{x-~u9bO-~o*FfaH}UYukn`zVG5t4KY@6X(XT
zud#{Z(=%)!dtKMvO<D4eLbz=#@$Y7y4xT9D<rq#@`Y2A{U-R-Odh@NYb;m}n>9(hU
zEzFCeUy|P(6-i9O<$7Df@q08wrYTiUJSQlhL<WLmjMLR5m;mR1FiqB|eLz?KA|bI+
zuWP7N!CA0{T6FJrTdO!c9)(4XMe@|4$}!t1b+C}XGE7^unk(UdG4_^WRYhIfD2ier
zAR-N-h=6o=C?QHK-QC>{Dgx3X(gFg~-O_?|cQ?}Au&Fb)&-=XR`mXQCIsQ^)@3q!k
zbB;OYxMLjt9EZ_Ll9|9?7PWHA80DbuF?)6|Thcoh%sS+1TpbL15;Qb-Zzo0d_R8`&
ztWkKp<zt3)(HC<rbI;*qq*E|Q;5aGWN~ZSi>0O+sI4G7=bxk|$f4JQ?b5twa(;^5*
zEWfX%y_~SGaH;6z=JE>>AoZ6FrYk+4KX+acBjRR%hf#JHO}VW+d<adA-mHwyrl550
z9PO*+vj}BH9d9k7pj;mde-j4vy5I2|yli$BzUlE)Vh=*Bm&OU{Xw~}rYo1NBSF?L=
z{f!7ecSLaF9jgWT#P|#|<0?Ct;tn{;q&wsei&`!nX};_Bc5#0cS!VDm?bY@6BX{+u
z>93TdRqjXNr8=HlH|Tis9XuVPQIaDzUlmHU4YXUB#z0x)9b~lKdQ%4LB!zF{1%8j-
z#Jczh2h(8bgGCv<R%FnmgoUQxlgeMRZ|WCXgEhjESIBBg6~|!S@MqZD>*gi;`&4WR
z7!JCS$PoLT)%T?p>`InebIS9~uqI@uCXM5yNA^nRbQc?<e=~Ppm@(uj=2Z``un%!7
znT<RUtb)P7Y$EHg%u!meQ(e=hoin_SQY&2>G{qK~>t&_DJCpxLP+<F<o3c3+?OR2F
zy1>}wof@Je@?KWib!U{lhc51g+vt&^bb7J_FD36JywfkJgzy6Mb`X!cH??!HQywK)
zh9M|8$fnSCZZEjw@83n)wx17Ba?MJc2S>l9<w-eY$*6P;{XG~O*r+Xu+rp@n>nMvH
zub`SbsyqtaGey<l54Fgr)tLA#J0ku~kkI_jlTXy)2X3qGhigivsNt+5-Mv;Wf{`M0
zb5k7Ky1M#8h#Gs8VJwZ%l++X&3u#SE{5&n$4w*Rn%E<iSkM+Y4?S7<LNHyOG=_|th
z;q+(vr0UcxemXBeBhzGy|JN<*I)ysVWuEvo`-Xw;a0sEu+hR8wo>lKsv3S9Kwd3Bu
zoywXi+&6MAZp*pMKxU43FQ|9*H~fbTTW!L(nE1BBMm^E))pv%DmK;Ca-(|k357ry@
zrYo&iTvyG7r*-*u_UotGn;=cWSk<!9=xG<%uzi`zO@~dg#XdBI^P>q(rOL7oNqG^}
zUM!;zkaGZHuPG|&d&+L975Q`=-egDX=bH}>N!GB{siL){FB<0c0#`?Vl4&|>5)cx;
zZTtCk90%QEU{%#qH2br`Ji28`o}v0;`iK{KEAMNEE$zvdzPW_WdpI2~bzNuh32ZOc
z1Tw6PR;4FeI(j-O4%{YA11sgpWN*s9M$Z^|7Uqjz5FS&(%P-xpj8u_L{}|WSviNrq
zMcXpXWe&?DqI9x@lY#YQq+XsqyS@DbZKh&H?6`|?$$!GXhRXQ=^+1*!vCGUA6TeWu
zgvDQb@x$nGUF|My2YF<lmw{K2U9ri^;1_8J9_C)FAEqHbWvlk|b;$~i-*Z1wxmgZd
zLRkA@PL)U`Ad)T`?#PL8OXAjL)o~qivAI1}w5T1+q)kT|wY5QC&QDB-_nUQeZE@YW
zyx4MJG?STrQtcse&$NVFVPU~rwP(^JETnX#D2pg_HV{vhSo3rZEETq9hNDs^i$}Uy
z+`FtdvPKJSXT=pXeF&40@2LN1apb77zZB!1L$1haczq<~O)PI}Q(X$beEi_2uqa0R
zlikTm+U|Jiy)EXS!k>Dblf2=iVZ0}sT{BD^EW^*^^A?qU1^~sWCrQ(PBKz<1GOG3`
z7OA~leM_S$#i}_v^NuEZ6xgc2j!UK2#R<l*I~q1@<2WxwaVqzFy$Ks3*?;Krsl|7o
zJ3D@ygju75&bi&0ZPz%gWH~Q!;nMpI@*8>c_`_7I3cq<QX45HZ^&AalW^JG52-bS0
z|4A(B%0?pcEVMJsp0y|5E2C+Ja2&&F^(ZMR>Ev{^+_ryU-X*IeQ1@_msB=OvwD(%l
zNrm9V$OimypXSn#Z@nj%k;TZ=>A*6lGk2%(_}VP&YDC<e$)>4U@Au*+z961#)Kw=2
zFLOSKdL*{FR$3~ZZgyIkq5sZb?U<dBUgJA*08&gbVk_AeA+&A;kE#7-FN`K;9?Ven
zCQ>j%*;$gXvR&8;CO`e8g}K~W%4%=bODe-F6D-kuY&l9yYe(B`PV(oy0;=+`7h$(z
zch)`x%D=-GYW4@K8Ase29XV!N_?%{(-CBY@c`F)O2D!*lyUd)VEtHGjn`stKv~_y5
zslTyQ=sf09=ss(krIe{@e(7uMrg7$1;&BSOi@gP^um<hhOZ@_cmtc@_8w+cBn11R~
znYbOqEhmt3$M8Ba1QTU?$?fF~iN1K}`e3eaZnE;&T)i0APiber9)7`?Ay}Pk-K$4g
zLsP_2VdJD{`)cmE&MQ5{gA~@JfzhD!-rhdJlAvTMSCfpG=e)??9n~RIQThqh=$L5i
z7^1esLNADE$+2ch7CagqBR+odxA5f{_I4vfZOUz0Mq7UkdX&-VcH>cV+L9Kz-cA__
zPD_yy<J;hqM}G`cYafy`1sTq1V}x%rA4?I7JZJo~F5WwPn7VJSo>dngks@+8TKX>~
z6i_E>nBAD!IZ|_t)Jl6+<d*8LUp1Y~wCv|&T#^5Ld0TquJJ)@u_kqvxZA$F*-_M|w
z9yDzhJ3LwZX!>SL;!6Gcx3gkgzB%KK$>^ifiFJjo-Jc6VV{B-mwI7$Zx>Ou&6~cJ%
zLR#)yU{xMsnVjueoCTPpdh`dThr{%HeRX-UdwlF=m~i761;zbGkGg>t7x>+6c#Zsr
z*Z$>++le5n%*O})IJZMFmybL!F187?I|4Ie%vep8^1EQ%$oV+b9jYNun6}u@TU#D3
zRkcH`nH)83$ep<li7TA4t;h{=j*O=bl)7u&+b3&2u~-<h*9l)!HaRm__=XaSVrU;z
z59#C>ZjFS)<Y;TOPM05Z_34f+eZG$yx*~>ZQ^C+5f&yC<2?S$OlAJJnbBaM%q_Sce
zogJYE(cu#T{)AJprR>te;s{p3!_&;x>gxHUu}bR;p)jQu*okN1#iC4`AEk|V<uNR3
zcKs4hAjf(iL8WAxBc^h6(Jzu%Hd5;KdcrJCW<p7ycqLquFCIDXfI?{F<iyB7$2yB#
zkPTDaq)t`K3$gq%4ldKtvC%A)*7yFCBnp)yrnn-V@4<jaO={BEK0T1mb|N_M*AAh4
z^o)TYQ+ArIdgG8qp)+gcdtQN8`IS@VB5F19j%C=Lqu7udND18I-MM3(zfBxlh0Azm
z!od856nP-Y@z#;nG;oA2>zgNiIT9?`YVlIrIy4#e3@m-p<I~4?8%7G4w8XR&>ndXD
z@yo60R-;XKKg=gQUU_HuA#}n+GO^j?g!YngOMfaU(t>_`#4>*ut>~9W8C*|7J)y49
zPOqjT*G#K?F!ic*?0EgnzkMUBjPc~b#;!;1&rRAgi~}jg1c6tlH;btbd&{k~po-Se
z{;&~jV30uz1dK4#2g)qerroyr!42<E2r2I<c&!Z&51S^AL9qwu6VDhJFrg>`m1IJ0
zTZ)j7&?9}70_|&nz@bA~4e2^_4%CCj#>Ux|mDb)QVVA`SCAQ`ivuTjU7=h>;Ftvef
zB}PyNY0UGbgG_QbSFHt%$ui%i-UZSHvJ5dg7IAs$sj2y>?&64;*Ky-9czc2m2#@{B
zZ#AnLpNi9zMM3lyr{!+arJh6?&=`QO;2xR4_us$8h%Y_PcUwS|lW=n4e13i|Z?U<&
zEM{zMT<Fk8g{P6{%>XGqvV;XZ_TkfFIG7ntU%Gq}^9h#`u<#h)o2K1nHrgg}{615k
zcFd_`v8#L)IN36eW9ENGg~^J;dTw^gS~T^VB=_!Nm>~X6N1v85n?5$y-lLsAWP<m@
ziM&%Ho(iM-?upmvA`(MfX1uHuZ+bC2=6M#Y=~+WC<!SG~|GgpQkBXBnY19CNT<SaA
z*dg=gR>!A>*;%4ja({Oxc4tOyJa0WGd_JmBnj&0-Sv`cHFI_Z(=cQW5-2by2ZvFHc
zJ~6)UEljH3Dp@!rGOx?zQC+^`^W5^xDm$_}ero^XzfUV{(!PGIWdk;ipw1Yi*(|e&
z3?f{3E!nwv*MHF@B0es7d!!cPeCxTuJ_c#G-R82MAgkSs<WcCf)t7WPMi$|6kK<=k
zZEamTEuTrBF*NV;vDi-p?xpw4NB~|<M}O#<OlG)4r3RjHX#lH#=eB$0U=A)OP*ZtZ
z<!Avu2;fNcVePw6lJ;nU4xLu5I(;Hkq?nAlNq~|rT5Q;!$_?eGJ6KpoAo_IQYoh|Z
zNhZRxDF8P|vqsh7&rhpqm~#eegPHn9w8t-Z4i9g#_1Lv{bm&1@E=N7{^0oWsc&Yp8
zVieRV^>p8zPksa}3v49uK~S0D2&wImJJj?x#)@yjpVAYU@6kLCG~C?WSqD%h)B$%V
zWZe%1?i>hZ&M4A}0vbQnrI3@wBL7dg{n@3(_(eXc(bv0&b*yT)18=94d04;;boru`
zakWTGP^M4Nfh9OB)@`oSUCX_Ju*UB)71(%cQus;CulR67QDAK6&av&?p|jSzigm@Y
zwU-_p-;QBA#Z<avnUY~@MfqLG{NYRI6MZBcb<bcitOYUSU+P}5Aki;8AfaxuYI&ql
z`N?rkyHjuE{KT|&=9u42VA@-l9r-Ba4bhbbG~5+Fh#4)3XkKfEZ71i^tFJxxy`DaL
zKk$YKk?32wf)iLa^78iEZxBv#cqP9POQSOBPZ${*J%}J`>a=9l`t<?tbshfVpIPr*
za4@x9>Li3ndD`Q3=?w)&Fm?qkfy6@a6-X-qRqNQ@+tY<o<Y2y5;>LzKyuu~`Yzf(n
z?;}m4Mo;>Regi|Eih|-3(uE29BRQ<5JHep|d~cJ-rD_FSWD@vd!05L>UrP|o9wpqT
zETP<(qh9fqMj>lwt7^MHSrlDTQj*JN9t6BS=_P(aV5>9_S`}c0vx3-jZ6sd?_=JEj
zvI8!!2L&^v{%(_1E=@8Cl&|+lxbEB8*?|FPJ>1tR#33Mp<A9K25quQ^OW>x{td8ck
zTgt#|Ehv2MsrSM|x9^CD?+wm~%wNfV!pY6aQ<>$fS%YoS!9!}p&FIwK=BsQ{t-|vi
z+v*KizLso<@$2F7ab0<VRmvyJLTL0PjZLfgLy@VE>MZ%51PeP~q>dEkn71vl#;MqA
zW5f5#SGA2$ZMVfy4wULBA=tP5vV+b1^C!AaJkV%EbAF1a(o~<dSC#A-fABB7L-jzK
zNzh&3^jrTGhvd9==gW=kG1l4+=QZ9D<O<i?K999i>Si`=q8_e0Q@)zu^I^cKVk&5Q
z(b?5G22leYi|+5AA+r9=mte0mv=~=A!(=o=f=8y_`Tc{PJi7j<{PU!%RqX#v3Hfr@
zse7ai=pA1y5@W*K;8c5XuxV02aPJMGh8hcv)O-<aaNSRBvlOzMf&XCRpiql70~`tP
z6AQ=*h)PWC0cX&_@Ni_sd30Q0Jn?Voh~}T+;Yh~1^REE70O<dNhtqjS8;H+85fy;-
z0@&aW0UywM8*A%c-t7c_H`7C+FbEFtYNBIe3cap8V>zwzBCk$%7ns@UFKz$AEjaJ$
zf-fhx^Uh<3wZXUX>oawNu&P157!1<ijG8Ti2M>}tR#vB~IJ>*MCF3}PQzfEU?3Mrr
zF!`9CzUQ%&CKZ=eqpO@yXlzHC@Karsp#zICJ=TRCQ-&`nyX(*8NCxo}DIsGvQQ@nJ
z3wr5cX%Tm#4;B$Z9zVy-MimPeJ2tg!DUNPmD@8x7Q}kA0`zc!!XTSWe{Tal8H#Ok_
zuo`Rjw^m2O3*M?8)VbfZJL<0QYz(@%nwGH(6}reDGYi^gc_g>+0Fg)@)pQGA&(g5F
ze)m@9g7Ql2*>U=`(c!4G>r;sMrun?SY?yC}4-PEHiH*#R(kx<{`-LT9PRAu<e{t3q
zH~+a*D$X3I^<5+k<QRF$rxp<B1ZQ|MNGYA+0P2e={MjhhX7vq?G#IM^H|ZG{moj@V
z&FsR0Ft~RPhJZnDSY+fY*jT}fIu#5{!8o`tN%$6WV})J#8c<v0&nADo^bYu@vBNV9
zB#icN$FSq3I%o_G44BN+){MW%ejlOG7H8Sq-262rrj0hgI+^3wwG7P~9wdbd{0x8z
zr?@$}GbgH)NyByItZK1J4EH+sCO|515rWxA;v3m$syE$9+>IA5l&{XHLP~f|{yyJZ
z;RQp6y3N<UoG<N9(ojijSAP!|W1Y2@wji`5Fb?w$3#McK-A!)khL=g<&l#z7kEtV5
z)ZFWec&P_<CCV(ttS+frw5Hy~@7E%STrN`mM)*z(FYz;yuK4->_da0EB!eUgaJYQo
zVC9P`3dQf<)*muuVD*dj@TyXEE?wfiX^}IS|H5>o=a^}*`-l>ZE+d~Me@C`Eg+^l9
z(sI0}MNM{uh~3mU;?hP%Mdkfc<wF6@FM03N%IIIK-5&@K5RF^kp_uA%8NCW{(a7By
zcqUt0h55yiD!9fgs#nbR(YhBAUP6ZcUcoe0RM`-x6{i~g*^IZ}MbEpQ%j4NOc1A<&
z;ExM8SMM5|PJAr6$;_XrTvCDg4<}e``{7LwPQfTp4^{XJ+p4S@8|v?&AzV<?z{=^)
zQ7I1S8fj?}TUI{kQk%Gwa`Tjo*D(kfPTHVSl5_9wZlCIu`OftLJ{iY}W)0Q>vv1?@
zK>ep5HgX*(PV&tBnphTi>4Th+>A``pIHF(x7iqb|&y}x=T}H+DVp+3g?szo54ZTb^
znpQoo^E)LA<Zbq@z7-v_GJ2Imrn&zKhk6g!biWxTq(!iLi6iu|?o+s^CVJ54P}!!R
zS+{r&1o`!_kx%2?e-A;FR8zw*70WgUKE+5+2p^$q)XO(KAQ6BJG9wjS*LYxmUx5FG
zyb<UA{TBdWDO_bMWaIHVZ4H`j$%rmtw5Ric0&Wquryv4mBoH}N0b-WRvze=`wS0g0
zen=~yvao!;gF~62Xx!P;V+7#_N&KRsqJkiid{jZmYM6nh^kcHxxszZq;XVkDvKDSi
zsA|@#Bi=<Ln)gZy^9^Nijw!!O^0jqZu)h5(xZ#DY;O*RD&I~;i>{u(w9ta7)L**~+
zPx-?UWplku=^|h8P<5laKrX*R5I2UCI&rP!(4=Frq$5a~<Ksb<4?@e4^6KKEE(>9%
ztJRfY$R3C7!vFQoI_1)Kl<9xD0RO$+Y3_~MU&K^qRI$GVhp#*nlZe!>QB1zp?##zJ
z)AAO&=sDN9k{C$7S|tobVmXcBhC4&IL9J=$dazOt)K)MFP6gLNu<W(jUy_2k+Xz1E
zgOS3CaPI!_;RE;yeg)e89GJsbRB(ep1p+HdJMM|Shpl{{3+g9d-v<N)tuVfzJ;VSE
zwYjkoR06MUZEXnzJ>A37MSMKKl>wMo`*l|rp^09XF@PP1M@MG_Y=YA@O;M|FTpTf^
zeT^+Ge!x-AZU;R;ir3X;mc3LQ4d*QqI7c9DEflik-)<HwXcqDX3v8cq^Ve?I|HKHt
zJ%uBlyH@%cLPgxMWq)fa_Hy2LIW<g=t=|<ly6@`$4G0TDC-#e~!Cy*SYMl8@^=v_h
zY*j#XnMw>dp7VwAmF#t+n?<mL4~yg^LGmUUB=x!a(Hm(?%!R5D#=UPD1^Jp+0kdQE
z=T^&CC#SPLgJt<rx~|DIW%&qq1^qA#PBl(d&%Os_Vq`RNii#17%UfbsOFoFivp<*R
zx^UyWPZeks{&VC1urxjsG>@X2?YOH*b}6vbfF?&G=t<%uR1eRtkY9m2{W?eIk1vqn
zzJWuf&GD87OvgVULIm+Tcq043AZIRJTg@WhM_YWq1U&%2|IjxlhYrx*-+)9ib8;>N
zi<RCclpcigkHHZ9BlxGTuCBsGzJr@6I5a4OTL@5C8TMkfYtKSpmwkYX+XNp4JOJ!w
zK0`?$dngr_%so<`Zx9-gQ2;V^c7__QNaciAQ*ri2V><?L{CIjOP1CXvn$oINVB09J
zZb5cb*A5SECLAKoBVPV$>Q|gc6zdx!E+VII-+~@OOphKi!i$hR-0;GU=A>3a@G@PZ
zSX57ZIeZ+5uEc1~aZ0yjxa5vlOOGaq=)YRKRk*07w&S=%d11)|mkIwG_AxLRo%Yh|
zrnj2eiWh2aO1hRza-NtCe2}|>`^FHK?%A!0p|$?ubb90&>+$wA_!!P3(mb2hi=swy
zB#ycJlW@_D^-VItO}D2e#Ro1XFiE+*F8NR}h}d2v$s+q7fSIC=jSZ2Y-Pw@^Na19u
zAA*%Rn91ck3UF{lHa3dD(Kc}7T-`bkbO7?Xs-^1iB3}KDV$^Ex>5*9=$9?|%Ijkfd
zP^*=fmv_r_z?Xoew7$DL#Px6uH>QeJr{M-z4Kx841^j>(;H`r?VSa5*9O6)57biP=
z1h`^`gUUBJ7{k-kGj%w%M7iCTv;+h(jbO7H1NJ<ci9KyybLT^_DO6m8da5Q)O#xH!
z<E;)|#LUG+<Im<FtxB_Rr%=yKLl47BlphS>>>lqZ5f|VJj7+9*E6~F58MG3ABfh33
zT@{pAmDnsw^N!^mtRYM@bU-Al9XwU>!ij{%U)^<7*vwe|nRJyK_dAEQn2Y`NA)F)C
zD;#_piT!_#SH2s_`*i6<715Cy)z;nBoECrq|NY-P7Jrvecf|(N_AULST&%?e9U*Ho
zFsb^r{yc;zq$!U$ud%ncA9T*oPc2BF=Z}La$O?vgLoBm|goM?{({2!Fm~8*H>IxcJ
zSaeB%C-a62BO_yVHQRRGyZ(xzC5+jvEzNnf7Np6#o9t>k*t}X<S>+B?RaWAuXlmiy
zy5&c{-!GmmVN&>Qk%#Y2u~Uzs$OJZ9_G!V@RL^XU*7Vb7Pkq8R#aF!WhO6bXKMCk=
z`$Ty#A2Q6TtL&p$m)kMgc<YJLik0$b*e`C*2A6wdUi37Vw(cQfx#aDrSr~ImD!<`L
zsN{Jg<En@XAFg+9kHA?Faw|#LLFTiNC+L`%v_Zm(L7L#)?NPSMN|}@R!?nTg`Qn3P
z+btcHv9G%tKd<g2g_d-(35*_Gt9S4wToaUca6gHigOcg4Ns9~y{-hiwJ8Ogo^V#iC
zjOC+?iG!WZdX&0rzL<c|i*P&Bps7K=`;?9C8(8&bg|J&rMuVdbkT*<zw>Ac9tM70L
z9e=XjHBGu)9*(|gMgP0l_dxK;L0EiL7ZlD13zcS^5zhU)<ZeIsO}xEGB|ZEQl6PbE
zd$~}M1%J9=<*c&JmvSR%XhE;xdM>VTJ)i+CLY#RfAdpZ}!Uj<#Lm@jd>5pq#&3-p8
zSe%NcD`9BK%ehG|4t$aEzoJTjMDEw<FWKzMgSsN;<wd8J{(?a1e4+sSKl7e}?A@&H
zUqhae4!DL^21Lfj1b8U8X=YyB#WTc%tDCNTfyMhRC0)1RrnaeR);=G_+v;>3hQZ>-
z!BP2Tm)FV8EcoIN(<|KUg#C8pPbpS#HnPX{V7-K7kRqX-&&!>1tVoDw*PO@h@E#Ba
z=ER$EfjqD}^HY#LYq&T1XqQ_J$}~)W%b%Q7ov}i-FIy&m3E)J_>AJR_3(w}s!S53)
z<w!gj7zyO8R5)T1Vmu?8lDD=oMfd9B9pW&SIjvbvDV&P7We3VA<K20%R|sFrt3DiX
zlzJ)?)^fVOOju(2Wz8<p0TG12JfuzgAU>;|IrC}}W=;aeKL9GJywqrf#pH|vaO<JM
z!{y=q-43v#x;ptz57kD!H!THlc7y^c*LQ1W2L?{YD7ok9&PJQOlhs~w^ob73!+qs%
zv<w~NGkF}zPj94*gi>B;B2qrt6s-NFp{!=PCa5F`V~qOvDXs9~%uT_lzkxMc)|ZIW
z2Llg}9FFq=Iqc)9LDEy8Rty8avS`|@K)L-rh+L~4fbSG<r(1wSnuktymwS0;%V~Nw
zU-}yuNHmuci+QvlqT^!2(_8fhE8kAGSBmEQ));G5@dHJGVp?2(bvN}>{GAksu3_ZF
z%{?n8sIa6c-<nDGx5GhjtOi2$0l-upr2~d7{h6dZ4-KdUr`mi7>Q68gO%u(+=oYuT
zs`rRrWBhb~{*=NS$<S~ebJt<zcHzEfCJ-d^QQ$49SLtQ;`SS5q!R4fD?tVK}A}*?;
z?96W852MAlh{<10-Zq=f%vp!jr3X`M4k=Tio626E{QT~21%S)~+ARwF1yA=)vC<On
zSj>6pBhoB|yjLBu^vo<Q4dV^5k?d-wq%)05lwZR%_6G7B{$>Imb^8kvmAcI@nkss&
zx7=oid>O&9l|7)Ho#4S=`T_6vYIgcH!1CjS@A%1gq%4Q$Bens+L(S0KCGNBR)O?<;
zkeB8_7t8l34!$KRm<6LOIVGjSe)R$LtoX-nP=m@T)VJ8}3FdD?28IFFN%u&7Um7gZ
zENiO7sNr%OSy<-EX~F?7fTSwQ4(mODv=7fJ#M2@Mbqh-ihBDPH+P))43-N_YZNB2I
zvz+V`ktVy0EcG|rLhU}}-l=vYJ*(fM(me8EF<gtr<HOh{iY+%_VpqH*w98AABo2G{
zAzkBnT-fsZ<(beD5)<wfi$PO^qjnOUF_7FSB|f2*rq<Ta;LOe9c4RK>N3MC_;|$Nk
zVM}yiIGa9OI(NRqL+f3Ys|BAqKgwsx;J*{rQ+TbtKkcTv=>nCT)6nCP9E!n`%uJrB
zsKl17l_@yzp{%S7gaP6nQ|g5WsM8Hsw5<MwO51>vDw7){chG*AE@n~8NWTip|2^8O
zoUN?ijeHRv{~_<Vx}+Y_vN>3^13tM@RDce3`&PNXNbt4t$l*<!<a4=8Kqq@)tu%Ch
z>eKPOHEA)K`L+~|P=ye_laiM+E-d%ep6P{>i9$B+lSAQA#Id4p-lG8TR8+VXb-)x<
z4T-kVs<VmA*{#ighkbflk~s26$xJDTiN+x@Hz2n7P^^=Tj<53m`-8LgXX~6=lbuMY
z^mZO`r|eY{?z=KrV*ynEna0e_96EFB=%>fqS4*MMf}f=W(S86l)Lcp?*7J<NL%rFn
z>Kq?1SUR4{&j4mqOo?Cr4b=l6lVJBh7Ku2Ddo(kvG8LZM67@AUM%>hp2IbQ7(mroO
zC1Pu4^QtSuA>~)BO$1O`KJ*`tWl;m-98jI$Ous+`42Ns7Ewv#}8j#Spw0^-eSn^gJ
zcpP-@9#5XfJXf#rz-=)N`K4U(1u9xuFSD(4mNFteZR(l;jgh}FH`Hy09|mZQHUNw>
z*X76B=|ym-{K4zGs1OZYUiDmcW>#i72{T>&hFc%Vc0A*b{ZFZUb0+B~bEgWkb<-pB
zVC`epI(>=u(rs;Re-V~XjU2oFT1Pin{0bYVEfX?uR4EokQ-c86-r3iWE!H81>J3~J
z_AR}k$(oAsp5|B0s+&%b7k%=}^)uB}eglX13;;MfO%iSZSWQAl3abUi`fl=6r#7qt
z_@Ynud0djca~W$-K0+NxppBfib6+0cgD>##YCbT9P9y6=fLo?`Ig<h5+_w(lM(DGV
z_r0=%1HPeDE@;4F1QcMR9{zv7{gh6_wZ2#9TOj;)Q;fg`Q%96p-a??P7xGGcX9+9c
zbD?9{-29&V2LImwd_Em2D@fxw(Qf#TM7B&^1_lKT(pMGE32X1ZuMS}K)z<J@)hw$0
zo&0~l=R|wmWtVSAl&nYhf=Y_U<H2PyfX0CWng<AUxYYdEj>s)FE%)7<NSK3^M}E`U
z(vku4jzu8&fkNhOz9#=iZ*Mpkj70Z94VTOPgbDI1;Pm&Gnkhkhv%x)RT7`zJnE?eF
zdNmb+ey6Co*aYmU;qXVaUjrt0z)XY=RM(($0pzfvP$2>UyTrKfBb-oh)$lz!2Gaym
z`_e8Rg>Hi|1Bkwf&_n?Gu9=MO^>vwne+Q%`uaac%6BBoU+kwI|C<6lg{KR7N3{=Lm
z=)hr*8peT;r({l#nHF4R!uFT1o-oS1tZ^N>gP8}1&Lyu$RMJ1KPj(boSZu8wN`IOu
z$&ip_Wh`>)HDj+06~mpoio8lIHdEpo8*?eK+!WIOk=^XRJ=vzy5!pdOp+CE%7_3=S
z-PX}T#ddImUX`maH%<vKpK?iyH8~=S@$KCc=|pLRt4j)K{dDJ^eX4<kk-~Um<2^h^
zfl#3^8S@Q`G->{yJe>9!jE^1-8&pObn9%;4Q5pn`;Fq+1HU|!N*YD%ur75^VVH?f}
zW6<bpZL}#6A6a^YzHFu@8X6kN6EYB^v-IGQaF2-XGfaof)LekJke!o&ca8d(mKM6V
zpo78a8$di_pdp-3Ha8^2cns<pkzyhuH>RqbmJx^RS$a^-1nW8(D7Sk<svNpqcU3!D
zxgwWVcKF=CY*UG=7TPE=L7lVo0C>KXNXqlz;5Rt-^#gtvyofaYC;@t_<jA|kGMZqZ
z07Jdc09=Ne(h5t?F}=K~j<&b8sF#QjwravwR^mdN%-dqw`ETELKFHD+Z|6tD7;mrj
z@HaKdmS<i#+x8~l$eH_tSk%?Q7Vk-zhBwgA=<oIJL~HCbcChlVf@0N2*w`bh(;leM
z!a#x4&M~iDM)2l9N(<VwTmJJIFEV*^jf3ZM6Nqmj6GyZpTHa_wG2HtZstC>*^WR^e
zX)v*~FU{7|mROu+H}74ZqzG<KR7I_-t_>*0t{~22lwdgZ4Gm2r949y=nuBaWv2W}1
z@5IN4b#Usoy0Y>)HPvAC4m&#QihvsUSEZ<xTT)O^$QBz)RXT2pr;10678_xCU0ra(
zG*|y+eGQyuU?u<)9NK^&4M};Nwt{kV>EV=T2!{N~LK3`$fh^!+UPAi|m}T_#o8!1(
zv7e`2Aq0)30PEC+<#glbb1Tj5$qM0~1pW%o3t-+2KH=hu244y2t=9G#`>B0ac$vYP
zTw+m))(4Qp6q*cBD!9Xu2?<exJZgSn;SUtIGF6Hx0mDFw-QX~q(KWWWvqN33Tw;+O
zV7onyTIrxBCM1N$Zl>B-noSi!6H{O$bKUF8!~4sZL-k)w_l%aaAQ0d@C`$PJdEMDr
zd7z^BR$1ASdaZk)RGcmWvo6))x>CAAcEe#+dnA3->i7`4*325fE^m~T9|q#Z!}3Dh
zxH)v=n@ox8(PZo4x>KfHOXRFJmaQG`#w20SXKY@F|KmCGicIA0X;it+ud8|g{K=c6
zMb_0Gfe*$i277;p2Xj<{pUYj37PtTc!mz1b86RIxJ3XGog!sSuh!#K#7oZ}8*8>p2
zZ-9d`R25vF9)Nu;bWCW4J}1$DMI&P|I8uT>pUHam1yYsi@9$5O2;IxTTu#c^m>RI*
zxHV@}QyO9p^B>SVBTEljVjvsVnNO5SIj~->=hxXn*M~~`)dm0nGUPKK{2+N@zcz?$
z%ayzS(;@~jm`=B;^q8LhA7B9HT0?~?Vxh=N7odePY$gxb&4%>>c<hX3Muk&p>B#L4
zR(Oc4WUxJ>xO0c_#*JSEW=dLFitKI##UDSQmKRxSu<b9!8zK%kU_hiq8XeFub6Ns$
z^PxcSvz>~3o+nrBO2~NS4m7>^DSNS1s3XkidUU`bFNo!PZ>+n_qA)A&RLd*)@7j=L
zrTwn{K$@m}*3S*}<1Kz@fWq`nZrenI%A#X1UBJMk?z)M|F*x|s3j6XAy&&ax4gURG
zD~6x<<C}2Rcg1PAa_MMHdd)i3)j2Ud>_1+QEduCcflL5yCoy_smSK{<>u!pMzA|e|
zBw(r@1Y(II%PAgcW66jDF#?rZYbK7{E^V!}`25@*s&$2hg|JS9=&z7i%2X?AmWvX!
zrcfZ|g}nwPoJvL!qvXXY&kR+fdjnMbvK-<|=;aa-e9}=zw17UOaP(d`9xHkVtz&ed
znyX&z90q2`W*Rd^jmZ{j3g3kN@=%y8REdYWxZlUbFtZw!8BA3gUm_%8fYo{fg^r$<
z*>0&%Xe7{YB%1}o%+Q|I_~6^kSC3@7sw!O%`_^^*uxQtLTx`vTUZ8)=-}l&iL#yfG
zP&4e%Unc3Xw$G(8p8q~HG<W<3`VWZvu7`Vuo8!jNEav4x^O5REIbEUggyO&40l~7O
zy}l&1IC+<mF`s<7y1JT)g@qj4J!J*LuGz<SEI>WtuW~(a6c%{nKJZIZ`WxV8k(Yy9
z;4Q2Do;N{e!M>zmUH!O+3OV2kZ!M=gT?rDU!t69PIS2?}x>mACsg8S~;4$!JJ6vvU
z4F!-Cm$)A^F7AS*Pfp;^5&Imzc6h;|1F08xon1}yWa@W6@+FGUjh99I%Wi7#@r)Lg
zmfi#zURkS@E8skUxr~mDWu|%@gLhZ?$a$Aj1kHH<kF@6@fM=I-i{5OZ5po$6gEw&>
zdh0Rg1G3<<CZ4E#uWMMbLP*zqgTA_Y@Yc1$!t&OhTfDq>r6t?7>wYygOY84a13a(3
z-`xudt;^*|&zMyfr4B``z*El8vyG(BI=@V)?5Dze>!}#8-c*Fs@wzgi5pV!HXOC-X
z&1v_vSii%uO-FfOEbxL2k%k@oooKg%xQ>8HH_VeUUeQi%7g9z-9Imucdmt5?2<G!!
zakzzN*2^VUo|G75xI(OWc}orUQg8|T1S%J3%=d#x9RR^S(6L<aO$)XS5tWs_4~YjQ
zCubChH=sLbPUHya#NUXE_tS;|pjB)S+|kbHdYEj?ta6@J@evUU`a`vQ?;aiY!T2J}
zHwGP%xG}}0pwKrrH#hG6@nH=V7%pMyZvkRUx_RSQk$#&C__Bfs8eJiaI^WGQ@1u+$
z|LqrX9PI|by*~n0w95@aQZiwZNKfx+X*D#nk$BfnS~G7vHSUut(ZdS)3y0+f2uF(;
z^$iyBR7&%!zlnL+!vc<Cn9?6BLKj^!x0odG4wf<?V#~<m0q-r<zb5i7&E)MZmmOy@
zMP>mY;NU?l?2!SiV!yMcy&}uzI=+A-blZZ^zJT4h_c8Jjfp%j8cRzmD5sAbD2n+RO
z)LwwuK?RMZ=KxwlK}~%dNE?>Z)oqX&pFj(y)0LD^<LT;(ZW{p3zkvHRSR!%&Iv`?g
z&E(?Z0#@O|r3Xb}VQ-&TtfcX+rAVCNg2>1S$-L04i3R_puhG%1uuZmgbuA)2=mrno
zMnONoB}f60T|2>>4XlI}&dejk=zKYhW%&&|xjO5;m5h6}{r}zQ^zY%}?|ms3C@UlR
z3`t2;$_2A@&=w2lp**@+3(aJ8OjD`^=jncrz5t>%aj7fbK16T!x2t5#9zJw~?9b?X
z_tBfbwL`8zPmClcrhVjjN5xr$#J{mUI#M9uvFFWJ66-I}!FYfZk&V5yM02tu>?J8h
z=CL}vY4ImhF7w`_Y77|}Gq_3le>a)zevZ9=3&qa0>&Y)^rnKfzPrpXV&&=}5$q&zT
zkLI*j-{+@Tt@>lknuNm9rNp4OUNM43VYJL5&eSRm?BcV#D}MbdFzg~4GV=h}2-t{%
z0XQ#)Hbr16of8?AolQ%xTGC4k9V4@l-d}*uyoB~kz_LL0Lj=>s876?sOGU}rh5u*8
z0^kKfGn(BD5BzJCNWB(<IiuN3zN(I637&re5CJ;2hz}Klt-2YB`6^Cel0v3#bD4#Q
zyc=s*qSq^j?xv=%>}HkOn(M6W?1mF%0{6&jz3J5$iec84R;z2!oAe3QAr!I|{ey|!
z`XE_LPVV;)cqbrbZ=2Q5Ia6Y^GizZQDDcg1FC&xz_R7b<eOwPWqS@C8Cdvg}QxAhV
z*H}&7NtBk5d9L&n=uD_o>?N-$pB-%x-BLp|lDCVEYb>4*fYN6WO?7@XB0TEPhf!3h
z5WU^fqKNcM=NEu#Lle$L2Ny`fp~5&A0@E1;^$f_SvfYV-GH?z7@&?RShUmELp2Cc`
zDQI9sO$k^YsLj7bMnV$<erT*!0xh&k-77OQVG2toY1X)k>QZwloj7pI=CwMl_CEs_
ziX`-=hNT6)bHc%$;JPTjopUt<;#;PLhj=nfYow}ubtIn*7;w}N??QLt6dS?(C&IqH
zIV!B+XwU<0^lzyjW_?gp$x9WmP<TWsW$F_ch`?}yJhsAGhrsQK!us-D5Rx#t@;p+F
zN@s1$yvv@HR~YCVR$Ef~`aHKVDZ(Qi$=uw~-QCSiCWfW{-7m9T+6~!!%|33^o6C3W
z7;d%Wo-$|<)h~51Q#_lh@5&|OcXKUv$hIA*Y5BizI0|l<VQ#LC`r&Db$wJn@8+JDt
z?hLy)!>Mp#CH5iLD((5t4L=JQhbmRyIvIbi<w@z1Q~_CHvBGz#H!9oPV*}lnf|VC1
z-BcQ?3Nc=#r}&W(5$MbM%Z3YQrHrH=JS;W)_O+vDH*d{jB4sg9CYE$JAU`Bs&t4>k
znu`LJ(yr3E7R9t=W8>&2o+Af>70xdsL^WyRN?hALJf6)#HLP4;t#5$*<zuyX^rQ(3
zB-M++ov-CRAq~q6gKEQ1tp!i_-Xl~{H#p>lCV~E{q2|`{?LE(u8egbQ0xSP?^T0~I
z?bk;+b}BS>Qjrl?jliz-5}s+`*TGgYXSvWlJf{}ue%V|@Tyk2Ak!xD2YjTzPtoayO
zsPR`8vR7q`8H@R)TGc;XOm9{0N(|NAn)M`$D`ZuPa1lS}G{^6M4tR=|*9hC;SeFU)
z?s1$Pugg=v-@jiZCns~+Ed^;xBn#4mO-w;S0W#?{pZwL=JNJzj;P>Vb(hf)*F-QY6
zk(ouVs-me(0XXOieE3lJ05_sLhE@1L^}&TnSVTmik0>?r&D!WO3j4`1&>)Vr#Ki;F
z*q8eM4<R9&i+h0ri3MKk$>CtW<TN{>lvfA{U5vVB*@2>;fhGb)F6+&1_OF(iJ!Yka
z1v<yPRfVO_CA~5`4cfX^jix~s>Qy#Dru=uE*+xybroaE4XjAX_l@`g-%KQ1!^MbI(
zlg%Z7uM{fQ=Rr>{Lzn7J)e^r}A5N%|1PIFO#x^+C)`X7_nVCg6ws$|z5v)sCAR}p+
zls^?6HR2Uq7?G>PdqezA@Ds>e=!*(Il{tJb@pypL=>7SE!DeguGtzRd&!-cihX(;Q
zNv+1R>EGL^t~s&@c36E^jt(k4&BNln!`?D4sE}j*2Q8A%jm-69a#>zLy4vnS2jd41
zAAa)ly9Mdy;_-~vGV~X>2LsxeN5=l?GmtU^^^f`EN7MN^oi1SBpI^GsaatJysin)v
z^~bXW84#b48w%Y^84lJ3?T<Qv(+8+8DJ)+FU4+k>`9{Uc^ygBfZ6^3C7|=oi{R1$r
z^(=Ix=DS3YlXK!}c`==C%(&DxfG8!_R`pK&b$`-*v7mS+In5m-yz4h=uY)6e;g{9#
zs&u@x8ELh!y%ZW(N~}_$B9ius#bsH4i7cjPB6qsEaive~2I#~Fno}^)HMQP@II7R2
zFKCR*7ue$duS2vmuE5a_tG>Cx7eJsB=Z=<h_YEUWz264^<pK<8OF%|#;-!A+{a*E2
z)`#ISGow?O7_fZ)7KbEa|0Na4Bab3|%Nt#hze4`Da<H&Y%WL?%3dq<B$h~s`c+l0;
z5vEF%e%4&R{MA;gJyi4Zb8YY$@~3;7`XJj2{1kU5t7laetG5PT$frF0g2OLh=MNkg
zpq0GZ{003(#=k#%Lh~`-3ZtmV7LKgq$RFa+Dw)=0mfi1(1(m|r>{f$UQG}-Xt}Y`x
zlqF)+*lpMwA=9}WTu`nys9#5y&tGsEb=^^E=~=1FpoQgcdMbmS&<uLdXfJ00s9A=E
zN2NGkwr|oR3&x1Cya3XDL}yAsjIHQUb9eA*9o|(-$<%;z+vYP$$LI`k<OGz$=h%gH
zKIvsmhR%v!vzF4fcdet;LMZ+`9>EDxls(8a6<Qo$ZQhuLlBrbUD-ZdW8S^7bP_nR|
z$sBT`*=OqEEK?4a=66H}sv)I&?C*KP+&?14I60?Gosy6E`$irn%CRpB@$-AQ=~`u;
z&$kV9<H+zHdOUT=y|pqe2q!BgmQmLXDCSd8Q59Rw2!O{qGcz-?MRExkr&mP(Q0wP=
zuHy`c=C9xR0zA$h_y^bc`1><U#qsp!#k*DHix}U2))oGMu?#5!&;~t4&=enVNK^$*
zv#vOVF33LQhg*fY$ZT=6yOhR^g+jFpK&g?)I>o;czZ;4kWmqxJuCHVh8RJ@)Dq0fv
zHq@*ni!uy-vs1dNIK$fF*m50OelzZ7!U%fN>UU?jLxmsHg)R6e@ZMY%Eq92bJ+B-t
zv<k279A)(ek<H4G>?x7WsLJAc`9<sjEqg8S_-*J`3Gx{{BOEn1jX_uBD~+-1w68>*
z0W-z};RkS%IGUQz=;-LqxLMEgCuKP~xisl`(-kI>JLcvz`{QN;zL+UO(Xm9V4yNxR
zr<HjkT6_IRD_=&#Bd>AU9s8e5QmD~@aoIray58aAsnTp+hJhM7x*R%CwgciP<W3Y`
zTXf^P6DrAKd90<p5$zfq$1e_rNueO~`5?)R)a~?WK3lL>w=0JIz;raQireY*VtZ!S
zZWq=pVw+EDS4FW*zv(wFsGaQCcBx_R<?vTUf&fkuBcVO}@X!sBFN53<G}`{DqU#^t
zyB~?6{E9eqZ|a0^*N_~Ato%&b;_+8VV*nCZR8{;CkRzj#YLI5Lh2U;3Bh7ZK23kG}
zW+UlraGF&{{2A+35Bceesu(dk@yGQW#fRIuji6LEo`1U~_)F_=rlQR*Zib$gA8eWO
zf_3F{{LL1mVj$rHOpRyc&;1MG+q?5&{{SfO)u{~5eXO44lrA#ny!gH5idREKliih4
z=UvX8S7%Nn^rVNXvJFk*rvWn!Dd>a~j&xAxR~N5p+(0e%mk6a@96&tJN63Tn%OmPI
zEHP2WZ=7^6#0mEM#E|pGtD`F{J2^Ypom)G4^xXbBg2YlU%>5u!ua5Ep362aWXmre-
z{6PxC0F%f*p|p(q93Fx5a{A?9QLaynKjB-Gx9W)H2LP~sv8B3cW@i?^uJid4C|<k&
zQJB{|!<u)A>Nz!EHj<nac&ir+2+Uf9(=poA>0B=s@;yL+$_i0~TtF^f8W}N^YM*7c
zBEAiQ!VGZB=SBD`ddtoC%z3_O$y~I9o+dk<R+*)S$zyG_Qqc?m9u*hcXRyT|SoD{-
zPX3youL9|zj?tfJH*3o<TOuxw-&MZlnukmx@P@0MgCt~-bP@UQo>B;G4z3_z19B<z
zXq%cNF(BAhndqH~Qq-bq6Qd{r5y~O?^;NM{6`=eFAeYkI_4FyI*TJo9P!}Carz^58
z2DmmFl3ccgL_EIWJNc5o{|uvoR$ww`ieSW&WMMpXAX;;Thlr4{4>X`d*C{WEvg?GD
z-?<lS#y5#EdWpb;$!Du$bhJkf7Uur}B5n>*iMWNZiN=~v267M!Thp57D|T|MOz9H%
z84>W0u_8u8vh5rXzh@Uw#_G8}y$MGrpYHeg8Cl9LfJx7n@86-Vv!`;T`6p_8=<^#^
zOPvr6eROA+mJC;zKJ~WOMtjIJXA1%R3Hiz^88>&R3+1!$kJ&moQE_uu@GW2iE`nrj
zL8TJ+YdPN-KuAy8M_7;bfqJLduKt%@NJqQ9#!?X#8Wz)taIbd!(faVOf<n}Go$%jZ
z0CT$bAIu3^^}~Jf59UD@p#FdUcyR+Nc+G%2UYs4TAD#l^0(yNlt`4Mka5DWX%s*+w
zdG-%tLtZWe#bA6;`5_P^xZt#J1P^(C-aq<(rQYf4`(3T=+9r+fh<G{EJT{LOW6SeE
zFm^JRPqve_CHnf}zIXGx*k1=+4SIjtTH9xzl}8yb^ra2<sK2iG4cK0*>laZCzsehf
zcYimI{=FkY3#0uX32pC0sGsN0Fu9aHGIIkXrsY`@P$w<n5Sw@LbK!FmbGmYF<T~;J
zmd|}_xwkKUL5_D+)y@zjFoYh=0CLtwTNR&5keH_$rtS4bhC-e!viS>=1CU46ca7&Z
z%;O4u#`mdyrQ975R~+%}TjPXPT`)Ko!nw1dt<C?XHySn}p^CYt;Q0<J9F>~D-34lu
zP!V_ur=6Q4FW{JZZ27zDz(l<km0tMtviI1Ws}4Y|mBsv%y3aM(fdH&2$`t>97$02R
z5uryuF!)&90P0g8l*NI>t<VC(l9R&`t+7f6THs~=nVHerWGy!Ang?RIT*pFjj{sQE
zfW%LcuW;1oelkUhS}2G8?dvPR$soJo`CiF^(NSb`7H&jb@@neC_UAf68Q6yDR_kuS
zG8?LBRPzVUfs%bI&^m;^)DPqA)ZZcl*SPi$#=1_pgap)w{X;{S;W~Qo*XoO-iSIlP
z;+w1htSlf2|Fge8M90My>$PA`L$O>Dnt*~H>CWA|EV33bJ;LUf%oi7zZKyBrLn;Q4
zbcRL>$A?EB<T-NHDMDfQ7=z6cvWI#3E`QL_MyPH9#e>^n@nH;i43{cTf1V>RNFDPO
zJ?C5$z0xncU{8Pw4UkI)8Y}#1Hiv?;A*|s6uLG3Npr{vf*eZRMucI}jnY#grg&ot@
zV_-J`iXBiFhln!py+4cn!(se;HAzFauMW)gk*PXGV&iL&1*uHW-Fec8E`g?oyRkJ@
zWj<3&3R)H<@h>7`FI3eV4MQ1P)B=<2yMRaR%8D`6tWyw^z$8P~cc8cowH-j~zyqff
zXqg5813S|g#}?!6%iKdUNErB~>2p(3pW3<gq=F7`sL*btd$+sN>2-&s9BFZRi4ml8
zL>*_#TY~PtPK7b4NECT5uQsP#l;wx6ZtWa1Z3N|9FM6IGkU?jf_E9!@UNb;7G9ps-
za*&QaYR@b!A~wQgDN;2pLidQhOC$V+sK|XAqZyGGFK_F|$IOtqS8!uC++zxvKRe_T
z2>lL*u{|}@Vkg#-W<QNSiC*A8DKVo)Y4T7U*~`<ph&jBwDdrsfJ0OYnF`mCo@k!bj
zZ3A3`=M-xE6G!r|%Q!?Vez)&LeCb#e8Y9?dJ~8h#I-JS4I=$%MZmo{Xe5Zy&Fk`_-
z7eps-nIF(m&ajXe;5EBEdkbFzUnEuRi2&832dH;kc@96hnH?LFhJIc#Y1WqjXYhVm
z4Gm;t=O=wxsoB|q;F>=VWLRXQq1R;qS!4_<y?%Wg<?-|9Z;D^yV6(qdQ6QYY=Y}&T
zI#$40D)vL|@qzt;HO=P3uiF%Q??x#|+}9tQQ*cn{(lvdXNqbyJLB<ftu;aArCr>Hr
zEY7t=7M(v>E>GF?b1MAHmv9s@R<Rqu(0+IJ-dpuqMG6zqF&W;wnK_+|p50FL?+R%G
zmHcgcj8A^0w`>FKtWOX+8#UGV-FV&6TY{uVX-Cm>f~aQFxgWeUQC~R{K6jt4?|gZ3
z<`ai+O};83rIpM7MeS=KsuGsA(mBJuLz1lijsEQ@&z9Aa0h*bfCkeu_{A1#blDANt
zOLrSOYgh}f);xU>%+q=W`m+xbUcVL@ycccGPfi||F@`V>sfBLJIx`U-tqkqHiQZ(M
z?yF)1tAy83vJ8fzE1W1XH3UB;E_gO~zK<o_+ZW%vKl|W)a1wD6)iA1TctP-$0pHy%
zT<Qalzs=Ybe<`$;({+@&?NfzVU>x4}S|p9STGG}M?gq<hTIZwC`sT>K{xNSi&ulnB
zU>-ackm-?jw{3WQz^rdLncncEN0y*Gx$-)S_3|`n4siu${iAvzjrS5LOB;#a;cZk3
z;$@l}=gF!anDoK)3YOVfZVJaJC@nal3&Voty>%X5zmzK<r!b+4;e_hK$c&a2{jtAV
z?GoU??i=uJi}dB@<rP*^!UypSVB3n(Q(whXk)BN`zo#^8#*l)Uh{(IpSp7Z<Y`ST4
z8UCM%s5p4Rm<yt@5VWPO<f)7%Wh3^>BWpO#*=M&XHXWBfPGq1^ebM#x_tpA^S9FQn
zSD~3wKLLVuLOqW`SDojH>I{A)w$Vhf<WHzx&auK9z6)(bohMvUyv{DU>@V&=*vIMX
zOG^<S8E#7phl{-6iWJDF$PbaBcH2>QvB;R>bSgff<oIOyLh#tDZUl~~x(#`EMjbtg
z(+*>rwYI>R8#|mHgO!=N9z-AoaEPhiX+T%5uzkkkxbYc?^>nHwx4{VVV`yk7kV;UL
zOHCuJ`KrMj5X{p)In8+BqueJV$_kc%c9yblU9jI*VyRfO*nNCW(J)n1b=P9uH8DKA
zBK)1orsPQXNjz|ijWv&}l1<MT^S}{{kynm4l|_$V4~3o8Da)DU$b3xP{Mz8;@fi+1
z3UYafnPE+~)_pkdcOQLi9_wIEo}7*mo-3w3l%;_5#zKNu(D_j+Nt!%N8!%k)M5I6!
zh`2rg%0K^Bx7SX~N8<hYk(!~eA&O}TmKT#wJ6-!H7}Sce3ZaRdWV%$cwRQ2=ok6DK
zb@OL;b0l-VtzDxgRY`E*%<gt9y@(@<9#+YJ9{MLCH-v+9J-#q2p84U2VpS0lsV031
z;jODzOKWQZ(a{8;G9v(gE$BweKu1r%d%oYJ*Ox51GWyo#PDi!Nes7hNmHXLd`D+;&
zKW}eTO6l*PfoaU&-tn0HT_7wPN3F?V_AvHz%wdLS-`Z18XwGR-UU0U=YVn+MBj(CK
z%@k1D2KOiAmZp!;98P6hFn((Cdr1?etD0!ii@i!cxE%HO>2e~8Pf<w&+s2#GloF%$
zmEaU6b~YcsQa{-|#$kNJDYiwM(c+=;pX~0N9@ufDfeUY1A|kOVr``yeg%2BB^jD6x
zP?EcjGmV)VHZ`$Jyt{{i>s7S|4LOlCg!&#vwX%BviKC)`udy~r_%Pf*eqPyS&KY3J
z;jh7CR$;z<DsbaN-iKbCk?*gf?RoFOm=i4XVxlk&+ELf~pP*r9ViQ!mFr90hKMC(Z
z(kk1t+P@(l^_$%G{Cs+?PV)p8eq&{Gl31}>k(z<=m8uR=GHdeg6022mwuaIiYh-ie
z$!rhS&hn68-*hFvCEiTq+`8YB2npt-vm2j9uO1c6nXd-XRwyx<&Cqeh@V*rLDYxua
z7Aqv@R>rWb*}U7hfbza^!XM>*bPmBB!C9W8hR=lo3KOd~rRK~j&-Cdg=?%9Vf5!S%
zxE>2LMCrZjc{7<W`Y+b8r-1ZvW1<}EMOQt6h=>gFQ~sysk7`t$dxm>#1koKh9uVia
z=mZz&_lnHiAbw@>`|k|p)6&NZ&WuVhw#ZG%`K-Jg7l9YpILc?px^&5nPxV#$F`a;9
z(zK#(_7~%8?5q}+ik74IORvp6pA$O0osS(oZj>c7ac7E3d+S5RsGCc^?9r@S*(0SW
zD-A_wK?0QTJv@vgulBNLvhTJjS}jj26BRv7B)PaDW=VqG?jXVw-K%$<@+kV`^*klH
z>1wn&dpP7z#DJWmpxn4|17H}%4hUo>(}UA;5l3nj<&G^$Z~Uxj4j)?nop~?M;FFz7
zi>N%pm2Su$YRW?okrMD-@Na<)n9^KrjC}Mdfo%l|>$ws2Ga0;Bc%uZB*lkW<vBPn_
zKf2v4U@QAn?892g>zKbkC2RL_NxNWKTf|62m@+CUPLI>a$!3UX%z&bL+<DHtS><5_
z?n_K=l1`Ezw8KsJt_ZD5Z50rb7V%|TH#UZvC01JzXZ+4&*R*qvmHD=h_@pTl8#mp`
zbu5iT1Q<Nl_$EI=>s`M#Mb@H{5|No&59n3TW8o(xa`3u(U_G9vqlugu9z#@Xq!!~y
zC)w)boaUd1_H~IzlR1;KhN%cMrfTz=S%dW<?JCS+(%$+?@AksaqVui`?(*_AwYO9x
za+t^6O3<Jk0Qvhi#bT8@PyXS2t^7?UFz);Od4)M?z#0enpU^G<-w0{w-;`;Uhzrer
zQyP#x-c`T17%;*=`KNvbA-(>fy8-I|_Uc6mNA_QUKN!Zaw81wV?7?4BJYZMi6Om#%
z^78upC^&;!%;I0ig3v<BXKF~pOQ5cP0ee~6N6D{LN=<Po!2=H%D)7WI{vfyc-OwO3
z0o{SI`}A_&v_VlHHzy}&2l91J_|o7auv0!kAatSK$~ZJScyJ4o<h=-apCe3ZkpqH-
zg#X?S%rkhBKFY1w+e#8j?hnty%7pu(sdkBA`-TkSMuS|#TY1G#FqFGrdnCp&13#~1
z{y{!2(Wd$m_cx^oGv0f_uKjtt0}F}se$ix)qdI(8v~Fz~JtOZ&L%PR{9FDRWqEn#B
zbYE6if8|q-Q(oXMU)F~Fk4)FI*YPzhG5Y`f-pbsd@Whjh#Xp{84dabO<YBjA`~27P
zLR7MhO&b)!%H@`%AauG(Mn-1gCoFQ%nu?$HbVHZm-!!K5$&R3X<@o51jG9bp*)I3)
zsDloE(f?E2SB7QPcH2IHNGYu}NC--Uf=Ei2ARtIdBaL)Oi=?!Gh?JBx(xtS3A}!J>
zAYGD@doI7TukSnO?7hG9@9^urcyT@Jx!1ksJ?EHXjuBRFWNsB)I%P6zxZ>w_&=7`3
zb8#kO!!B3&X?z9lhw~%BIw6;i3eoRdP7}Q$3Q_*|IVJCOJVi3e@V)R=8?jd3i>~@3
zp|_UJRkR+3ber(Estj+XdsYqBw#$B%G0yz49U8J^aKDNY`qn-zfM0`BFeO5uPv-=Y
zZ0I=EcpenL&R}F1NPRJk|MS#)GgCq5dR$;mz+A^0x>9a;`gS)euDIZ~V58=AOx)wJ
zeWtbMwWiUKo^Tn@)qSf7j@WO6DHNAOpI;zxRc;y$FPE4M%_13zEx~GRIAVizcg4n+
z`82$*K}YBE(ons*Vv4obo8Cy@AjN9VJTF_e;G%%~y!y`d&=9#}2n}i;9)d6qq^ho-
zrG5tlw4FDnQs9u=9sJ7iwJrJ7N#%Nxgj_ITfb*s2sgbns_=#M3E-6NGh{LKZnU3S!
z39~cqkCBEfoE%>4R5xE*wM0?~M9m4a2K+Z88y}tpeZJ>U;4kV22m1U;><cCHJM@2)
zd0*4&zT^t_);2#LeO^9mxr!sHCkeSD-yh0VCysLn|Ct&M@5}Oe<Hw1K`sbd1eSHy{
zrp;f!$|HMR#PPg-*C0+a!KC8A!b^0?Dc#F3_<4!-lVCfB#%4%1w1f?L&T3AuShM5b
zjF>Q7-POHTLG$zOg&l$(SuHQE%(-aENLw!3hjQ*0U8n=jsE+4)3w({`zYqs51UP=#
z{;nvNS8+il#k#QfWbs#KO@`Kj_0PhqME$XgG4+Fopu3643IHQ705ZQh5R-uVyI3VH
zEiEcKnh*x)G79f+SG$4g{1S{W>wE8MsB3B#Oe~(lLi3okU%EuWdjZHt?O?4N>F<x8
zeg=~lz-~}UxusF*0#>>xKgeN>c7AoE`~U%AgigM=xHwF*GyA<2(S`r4v7hyq5L3$|
z1+|POWOy3fWk2l>D2~)PFm`^sl8^(9DkAths99RT=$yxP>^7od53!)b!1wgWOnrla
zwl+n>(Fz+d-_Tow2|CCOyq+VoEu&>m6ox&|YjALI-iUe&Lb($HI78l*M!|#M%?{v#
z%l)L26s~0mKIzE(@Ty0s+{fYtJq!?DDmqclN$@tfh<e;zkBh2F^`$`(j`6AIt$*oZ
zOd<`=iO3n~dKDOh=`Z51%26OQu+9`%7db?uF=d_I!#6~gS;XQ|wVwAoEx5Y^g4mqm
z+$~++#7iX1_Yu)n($0hR@nHBeb6;W@Vb1DBWhI|X1Z5yFL0Sg~NfD_{l=`Dbh+F|k
zRJXye(+dg;9MkS8`EP+opCJGixVA7P9RU=O^mp%2#--%YW0H1v7s$`g-+DJzHzvg;
zDoSf<X^DClr-J6PIm*hxAuT5tqV~JQX;B$T;1Ib~8yhQrzMQPAYr?|R#|N7o0K0|2
zy5X$*9xb!1P1KUWWA!;yI!^<?8BmY~8+!d&T9`p=?(SAv_OR}l1YKRxvqKYgb#)X9
z_(p>-4N^Rxo!5Yi`r+YRl&ZG&%|Tlr;eyU*GYkS!e$r<cXn48u_WVv)L|6Pu*QM@j
z#GwKF3qSZ8!Px3{QMv8I!5@pKr$g;31xf|{tOrG~l)*?0*Ab0i(FLz(WbtMoQAM1c
zQ&UrOb90-3+Ft_1#Bi!R_?pF!pGQXGBVxb+7#aeUvIO+jDUVeSWMB))vmw3)PStxB
zOfG`VMydC)D~Nxa0OsKSE7APg)i8&%lV^x1gVDpPe8eFXs3Mf`Fq%OaD-eUXt2@4N
zdq@WuDGZE^$Os(_qPBehP6Eq})EOWqytO}WX98?W+`p<&2$2{R4ds}KLDq%t5LAtM
ze9ye%Uljq}0&HMt!Se^~xe1W(1KP!4XtLnK99ns{lXh;{_f8yfg8%~b%>4Xd?%|J0
za6?CSJv0@A($ndYnnfvzf42T$N)lv~pl2A&y!Sxrt)?gOR9kYGg?YbnI_K;o^m)g-
zkmU?j@a0*0UO#xLR_1i~z%lk`O^h#w#sKS5=pL!b7kLzlK1hclMsA_uM{WC&eeYEw
z)o(fdriz>ib3llbfbn|}!p8vOZ~9XZxPk6*Q`wVmgy6c#qy{Y`X>jU%{~#?AsEJ-c
z<3etG%KJdC^4M#C)Ep6EURqv8CZxfiHCSRCmP|rZ^Hg_cef=^r3yyeh10Q+S)&O7%
z<lOJ;BLs&^i|MoJ@0HM&4g(dRpN-%Z>FDHSWPQAOX9?UcfYaMZ)<DZ|LrzRWLPSd&
z2@sJH^Rki2)A6dyF!b00l)#yp85D|K*qs}mLcX*A&r_Lj^5-Qbz6T1o`F&h20~MX#
z$aA}m%*fn47#ik?KSvWpF#X<~&?Sey;YzNmj;9@DERFZzm|8N_+fjVAmSMv#_({$J
z19irEHbPX5@$Fm(|6pjt!g}f|DjMnpgY#1tSX(_0DmYP^Wt-{54GIZrA4fteaL?K7
z_SoC%EA0cj|J>2cx`+!!Z*OpAWhFNWBjgsNSwLAtHNlv2fa$j{U$8+AMg}po9W_r&
z2MTn{*$tQDiqcXDhG<6zn;)Vre(>@Yc_zv`DS|DiygUxX@T}-ulpmx^z?~}fIrRX(
zA`yVlWGjFy=L~}I1sz0f2go)&VvAtl7998x<z9&ljc={37~V&_%|OCmIa#y*P(Q@J
zU0@A?(d9J<l!U;{vT<&d+FcS}+^0^pJz&om$mI4~wHMG8kbF=WJTLS$_tm53%*x;r
z+0|zUi?g<i5r@g{mqr9oPz^+PX3K%r1U^5FJ*3^A1%Jx4&6+I)O_I5poc}nrud<iv
z5xe_^EAP)4w~)m?<Hz<Rixuz3zSmC!;dn(u;dWZ>GoL#w5PW{pf#x^1$;rr&(f-|{
zOv4jf!pBE6l1}Wb&-Gwa9vuaC03mIB(_k8Ai$_8dE3>EV*(U>GfXWT+oH1S@Y4^_<
z1{0LEtA!spe7D|(){U*Mt`?9!T(1<fv79@-<xk+~?5uuRSGql%-B7dova)Iui$IA!
zqazkzfFM<>lKBzhlhiFC0K+g)&QgNpeLkqy0qh{tNRPT#$k_hAKZ)D(+~y?ZceTBt
zOtdbc{^~v@l6{hR#|B4g&;eN2h4c2sAFN+<#>(AX);bgwEhmeMCiWf8QEQZy^o_R-
zET0)GJKzHthPt=zmH>L#bC$P99qsM?<d`JDkRB|de+O6XY;6&q>1%6;LU<u1Bm1j6
z1r+huoO&<8JSKlK2PpGW3`8)nrK+KUDI!uIT=n5pTue;N;O5<r&hpPNoYs$gH1@r~
z<pd1{WF>;c`xj|w+9a>_rU+r7N~-M|t}|46gXG4|A74#*10`?K?#@hMy3A=F=nuUF
zTAa=+3Wx|Og>omUUH5-vz{G*PB;F+KRG%*4y&z*)P{uWlPEUFEQIH@Gs;I{sBYY?n
zO@q9YxccYUJi7L)X}Vu-_B^*`(;Z0~Gx=8gR`OLcM=}+SZiy^6dJZPTwkw0FBgL3*
zb#Q~0L3%{07J*RvI-$N}VW_p&p#Ow_iOED{@K8ZnT6jpv+hCa}pX#zQ2}8qc(6~lM
z(RMc`bp@D3Ak_fMZYyLpS6;VvgF*xB`&Li`3Iw?)daxv*^F85#`10O04a`BXv9a%g
zA~AAW1ZGYtDkyA0&MUzji-ww*m_VVx>4>;9zn}mttxj@!E{HSa{b^51PM(<Y2BYI3
zc&~s99t2PbPR{Pv1xMuI07npMh@BAWCf|&o^zqc!*Ar1ug@NVF<Jq^OCtH$C*RS*S
zNzVOURh>HLyy(Yhd|Z*KFz<pw1plobix7#hiX?k9eSg2PV9$KSyktC#IpsP<pd`Vd
z#%MqL3$w!V$HfNx20&^N$n$W2uo^&=cTtLI%xyU=Ly|1x%1aaP%hfV42fJkUY{tu{
zMpNJG&t;l1mgXH`|9Q_;0{&OD5ot0tkky0lg-K`J%{L;R{2*^+WML5kqqDOqS}-i&
zpPEVwx<t<*c`^cGWsB-`Blur|LK!!-tUkB5xAga`7Kv&??E*Hfz#P1cc-%k(?z1ru
zvMQaO3SB8eWP*Z%?x1zGJqs@NFc3V_=qm<JQ!&ZO;jdm1yL)=Fbzk^%bcBw2e?QS5
zX8-X)re$k;yBQ>WRz49RXFs^DY=M2ZA*7P_PEOzg5Jb2M9U4j(Em`l^?AreDoJ~Na
z4UoMn&@2ds1BvwN)eIou$;rtPzP9F<N;&*dpHK-O+Fx$|0A>}MfE#sq=Qn%^G#ru^
z-xKzmEO<=0upe7f6owbgSZst$_&PekUPbw7p6Uk{Wtm+y8`zM)QFNoInu`R3#Ot`F
znldU8YGDmZ-#jF$I_$4$BlOYi>}<p-2!_UEl9KRXL<8i*sE>}05I+Ot`@ybbO>P<n
zjejJ~f|Lq5HX(OY-yq4Ae+iXzU(N%%xP*i`!0Kz<w;3*7zKmF)<9wBY9aRG6UZ6NM
z3*}fyWMoirF(=U8Ux4Weo1W&qd#EY*xy$Mr8ncL500F^=1A#rC(<3856ztvHWZ~q1
zKMaN$4^X9=Ly9`cxRd_$3@7VD#wOM>FhC6KSpl~VYExc{D!XY;_HP9#>DD2F+XbFn
z*52SL4HFp`fGHda<mHUAGGb_6wE}@R(Dwm@l{NxUKqXb<w2A-It{nlR4c}S&g^Dm6
z8=VJAe0<YIE@dt=e9Xdp>wRhrU<kA#F`sz2-X5imeMfDIF@F*T%LhpF{qHls0Oy0k
zqN2b$=m^ii7qx)<Pw`BEkrP!dEo>O14{W7bS=|u_OC~ubC7>uH(qF3+ts46JkpTf0
zmR43;zJ0?(R@`Hc6>^8!&CL(Dk6}fF=jTl!Uu}YBBd{+)T22aHdKg_@5#FW0c@qb&
z2R@8a;2IRaFP9CeF(V@eOf_jL1X-;D<u%>jUe249jV*A&6Fh>D`vhJrP&}Zsmp@Rm
z^4UP~hv!`|3ql?@2sOa|6$dvbUS3{ENBn?OFO;gyL~I1(Y+y2NNi`j+&Ii>DB#80n
z=MOcZ>axG4B8g8OZP<QEm+3m+r@}uDF4b$Cyqjhcg^WQ3@dX2DBmhuGcdm$$%fW8|
zaP4`L`U1)j0)Mczz>N6gV`*(&@Oxg0rsZ}+_?C~Enb{JM$x~cFH$zkK(TNYic(1xa
z8UfJoZMQ^Jf`Wn+IzD@Pc(i;k-`G3i=jT_DEfM-#nJ%ZBfS*q5<m74kUU6|TSi@<2
zEarrQiw}vAhkyQ{p<afCZTo_`BVwc#ck?0T4>!r}VKq1+;JBK3PA>I;!ijOm<3QNO
zZLQeR0NPwOkqC73b}fckcXx>cyu;v4CNcXBNu0yxln5*XgbB^@SwQoMh$^)xr^}_s
z_+V-m#EEA?hyr<`>OBwokikG9*Gn)^IEEjEAW^w(Kf4~`9YBsfml-800Rl)c^?}$r
zfySGq5IZK!c*sEQqo7C<iu`#h>HVry^t!q_*3I&Pi!KN0e?LzI=YIsY3=!wb-8Y@A
zo&LwXZeCvVCI~hs714yCMerks@z#sd2nf-j4LM0&O33#W6jbbIn$T>6#UF$MEw~99
z%>M+m9)UQ}TQ>X*W(Q|ym{Z1NA`Y#ROwS2uY!o{uU;;Z355AkD9w7dg#D>qn;L)P4
zuGwUrO$Nm#f~mYducXfT{$TFusNUmb7oyDS2pI=y9)|Za*lAxmJ7s3-?xC8}tMQxb
z_Zm0PSF6+MJ_{OCCpyoUe!L1TimWT|jbzvGlNE#l!&@$exO}#-o22DB{uCagCo?oU
z%z`1-Y~CRzDP?s5@P;jytu_D+TE7oHH1bM(9K_MDyR{l<5TlnI!Cy3Hn7k=)X+=P8
zT`Mi?SXpXtU^}~AN@|cvdO@0e=R5iQ>v`NKQ1v4DGIc!#0IQJpU4${~unVZA5NE;|
zO8S$&G>y2x-4^HYP5y@FZT;gtzGP*gB1f-a7MiQ=c59WWruoU(7)KWAbnnNm)IZDS
zqBUOyS9{hMsc1gd4=)|>VAy&3Ud2^#{dW7gAgwG5U0`5Lpi0Bi7lsq!gRm`^Uz7LQ
z&#murPS+K>7QU_9gcDDcHd-9|9*&$l)N9>qrN@<%HMft6U;Vl+ZhTD~nrx_R413cQ
zuS4RnYqV?A0kVf?6KfoXUt^f-L9@u34z$TSY0?PJsNvJvKti49K%d&@*#en+#eUOK
z?jB^jxZcv{GOfk&H2a?#uyD$W?QJ@Fc3n3jK0a|PJ@~DkJ_$A2;q?tNxl2r1qNaC^
zry|4$cW-zJ&zMjv3Fo^OKKSX)!eEsrP!5|;$+*xw{BkCL)4+&Y`lpW%-N=_HukrE`
z+d2DU@YY^ZrBHQmUd4nfAxr#^qK+`}Do&|fc&f4p6}8>C;`nWsn*{Y&Q3#AQl%gHH
zXFkN3BY+h@pb&TjMNI{t9h;Y}k?C`2W(JyekG4=i24~!N@WP&B^KIY8)?O>h@2<EL
zcmB5<=_eYEnyTvh0UyrKbc(e2T&4kc^G-&rWSN&u$MbsTKdTHAPSSjw13X+^z5r=`
z!grqC{7K+T<{PIGKkGI0Ozw$Vvb-1u9TpuuPyg#+Jw@oY$vmYBwOy>Hujkgg*^ln`
zJKr(zL;aZhO}(htS`yT|tPH6eibx;VNM^;yTkj~JW;NCwK3j*i2MlRdW8Y9Eid7Ux
zIng1T8k!=X%{n9u3ZqhOJtYh@>7X&r@SVXZ*F5CsZ{tIuf~q*BSZF}Fax`8)2}=G+
zeaS)$_5Cy_Geug6e3=q}YopoOK-}XZD~c6L*7(qCYIir<+i@*^HGp5~(cfo6Niw5z
zOP3^(GW5%!oU_x~MQEdhNE-`}?`unCNeL4j2l3+GLZQmh&6~fsleBxZ6NXCV#yw(S
z70H+Pt}eI0y5|t3Q3O5^Pu0^n7T~%f%m29U_x?IYNImR<;s;mQ(w{yE5QLRu7p)_|
zGJspbYY_;|9*vcU$o;oZ4bq}Yme-iOF1^8VVsv8q#qx7C<U@>3^jKB{mMeM4WmT%J
zwy#{E?;YZ^ae6IY(P3*$+{^9gqs(4jD7>yxD<()(qhurw?d!-UKoCZtE6Bs!3izj7
zT}r^&`mtmo<ItlwmnnxV$%j()!;q5gplwp37En<5zjI3w!D*Bu(Qs4SWt-oSE!}nM
zR4g&6(wjcw>(V&pT@?o(w3{`@E5X1pkUJ(K4n480ia!TW8lVMif7_|ha_0@#lk!`Y
zt@{bpbEB@k62{k_=cV6Fb@IhGnrkIhzGhR{hH=$o%4uiDX7-XuDJ^w3HII-zzZq8d
zQ|B~}*}sb?<yiZ;c>NlLVO8i`DkvyWKE;OEi(}SRBCV!Y7L*AYm4_qWuj6bOlVy4(
zlQu%xp7@_lg1@01p!_T}#K;)=x$TD-J;P7TMZ_i<`58d{h4JCfDE}Gq|BD95zr9#S
zhgt&HN5hFo2izyt48t=AijCH`UM{!!hTcb>S3J|%9RBVxDfIwX&lU>|p4Aib>T_BE
zh*#NPU$*Nnw|($w<c~Cmbaoxf&7s%tiWdVz<i?TP=r>tT(ciQXy5Qlz^$ZGD=!G*d
zSj81BR<+z4M$LJh>$Rv~FKVf~wTeR7?RnwBo|Kp@KGeIx%GHvU8Vj4FbbnB%MyJ*|
zcTt6DTD~3Xi5u)}pM~nDo<sGu+Ee%<;`7DKy6~3npGhO$4tJnDgB@BT=vdje`Gu2l
z*5cO<FYo1{>rkVoXO&&3BG$c7huP9Ol0RDfaYi2v5bzk)H)wjLoMY8bqx5^~fdqqg
zuSknZk~QI{^Oz+x$I<fc<5mwn-E!LxhVHA{_&}!`^#kF^q_#W#?=`4)?WXAfix>NR
z;s?8pX#VP8mKNn|v+sGqGfkp+T1+^bHk2m;chIvt4oXeH5-V6aRpXn&>fi#ZO4ZKz
z%BLK+ZyUzre{4aiUL3k;1nXQ7MIi_t3La*BG&yLW9FfsKm^(@)ti15o(OMPm*#Ww{
z`b#JN(duocZP;I>7x`1RKOOI&{1hy&i{3rL0gN|PUW6rGM<?P(OaajvQTXQ*DQF`<
zS~}=9p9+ALn@%~y*Bf&tdQ~*$Q~t7yl=uxqrI!9KqH0CExq7jw*2LXgxDJ%d6h^A&
z(%9>iWAoPfjy5<xp~sj=fOa&;Gq<6v#{rfNYulKXe0A(rPpVtAPISJ?Q?}B!w`9Xj
zz0D79D1MRu+p2A3GPqG5Gh%4@MXfOMaRgK?8q2{;(_E*KT^|!!I|LfW-L=TI2giS%
z`JP)p8!kEP@(4U4(q}9&Uc#k+u5s`zFS`d>wz_sMRxXbvk)k5c%wsBvG8bQ8U<7GV
zG!Vm^cG&g52uiGNkH~C=S)|nOATP(@jkBIJ0gt&G01X9XvBKiQCgUEsB_U-MpyC6E
zZD+wZI0-)V$-+S%d7V}gj#^<`5u;pdY?0E`0j>X=?lXAz&E0#fvBpqy$$gRc%S>cM
ze~e*hW)TGW0=1%W5GEE`Q+=h7*P8cR=Wgh^m&A-T4L6hFo8jl?789C15k1_&2#6rC
z<{oNiEnsa;GO}a%c!LT)2iqAh0Qx`5*(nmgQ%vvUCI!5(qX~cwo*ke4=Jz=1e8PNd
z+W;mK2|Ke6g%<3(#JCNL9DEyhg_Ltr9@U-__R?Qw)~z%yH*sL!CP&x9m^E5|4o3-f
zgAchU*JdDejo-uMzr}}@9rRqcM)mBT!~7ci9du=;l-%00A=)p{j(T2zRl?>&7UY31
z4P9@mgS?`}fRL5;zwO6teutO$BS>H6hYVs1k8fxrkspqlbldf5y8Bfd6CYndw<#1J
z+zL$r|8s3m4~{XN3Z&_byNC6GMoK~%J;;SJC|*(%>V~T;#E!&-bsVI+y|!(47#l24
zFfou+08~)m#R-JFUJBdW4*z}&K`tFe9pJUMffXBbdqP(hRyMmh6HI4tL?q)OgYvV|
z<}=$!36&fsm|d(%;{n3KzTRjsG(LA-*25r2!Nw5>{+Ryxp36k7o9u#v!C#Wn7&}5z
z()~}`lib|@PJ1fX^;_x1dpC8e7B4tgFg9Hmvr4!|#2$xPbHT9Z?5;qfSDEV9*Hx(`
z4Ea?5h-$7^*Jn&O0=`tdmC7$EB-Gp~W&o-k(-AR39)lKM3!IF=kVm!yAd(UYMXmey
zi`Be}hbR;zz=csdT<l+8eOri@#D6IH5Xf4$pC#kn;WBLL!O4BCF|6&Ivm4o2F1Yft
zI}#HG>iET57`IVND@(?%eKyo}KG=)pJs7!(&(Zvrz2CESeS$`xk=16NJKGvZe8-P@
z%a{KxyGbRdXD6fQ6y1-;LC8Kwou}5lZSzXtsZaObr=b<o@ACBh=-1dszp;I_R!<xA
zP!7p``Zp5w1Jz_(ae@noX)-ph>;USc!<0pa9r`;nnSwM~vB%#UgUCMVs~mkQ&vq*R
ztO_fQD!JujUcRfDkPCSw#o6`Uwj=C)Y#E_2SMH%ZLD&pZSu)o+h46W6@0-k##gn0-
z0G-yzcluYtlTKCcMk<fe+9<Ix&j+EaEKV$_dk)g2619T8VS)#EsH(K-NMNDhu1g38
z++fm0zC+oq%7?54ljnye0S)y3`UQ>z4w|_f8n5wk5SMC~+H*Vkg=OQR-qpK!!i_Y+
z2?b%r5{DiYc->gZ$jlU6x!Vq|XeADM|9+QVY!usm$o7W|)l|*p!^WOe=)$*Y6?^n3
zFwv-+&upTb@KuaXqI4qUEZlc^H7%0#;)*I*ZWi27EOOwhHD_CWI$1i%?DqcRd)$Q;
zVXl=4E?@(W7bx7)B@k64plWozxUBy}B)bmI8I8!=yB4c==`-qhkd#(tb+Y&llulAv
zgI#MAzE;|Fi=v0X$Lu3p#j{OPFev=MO{H3(Ij)Z#M({$Nvkm&}?-&PEb9=eI$^xLR
zM5)U}jD}*mNF4YZo<g#maJpk*!~(oeNEW4J+HL7rDK?|HpyqYu><a1~5K5pM@`B4p
z@$j<sgAZ*-s;lV*4|moZGU_Cj=Np489D5%DlL#8<s$=CYyX~q#rfX>(%S?SR{2=8R
zbC78z0^vmMe)fPyzr-__+UOBY1-2gz(@NR@5?Hzi`$$u4h34D`93Vd@oT0onh`eX3
zwM7E<>nOo7=YY!3bzkT1>I%*&Y+UIYyMw3vOBp~#L(_y9^8Yu6)38j`y7eX=>P?v^
zE^LjamJ#&OY7(MUYJ5c##R<;(BDKN@y;Q#cl5fSE@DILKi%>5Tz>xm;*ZJ7LY^#)W
zx6a2a(>0pfw~p14g!!c)2Zq41-JC`@1MTh%*h>@a4WX^W1dvh~OB~=Rz5S!U=))Hu
zDTgKgR2(^&f@~>*u2o-CS73v?iNv*(E)Pe_u`J+OK>S!!TBjRR*6qb1`Vj&7Uq4Cl
zzBzsE3G}=b(2CJQdP9S?WW)8>J#ZF!E4(ir8GFNZ`a5bLl!x;HZ>vj$n+ziVl}@W^
zy~<}@W{?MSLbSi9<@Kgz(dK%Ul0pT_5Ze0WkVzv!vn1?%Uu?|tw$5^O%WEfH^~g$|
z@ZIo|XS-&zr}APQr|g5HayBKu0{L3hxB*x%q^qQjZDnQzU|nq^3xz7YKBU!Whi0~(
zl)cqrX}j&T^&%;r3P{BF+!bn6L|d#cyx&iRI^ajGLAR0e4E1NTHU@;p)ff*2)oTL%
z$k30>{I%!j`bQtO!UB$76}>)8CgdZt^-42^nqW8J7Ju>Gxb#ntv1DZ43cZ^(l5vml
zgM|c&R0}QPJF}=k-=lM^XV;%$FB4{LQ9xP;oK?Sq_*Kc{lrhiz0fJV>kKqBDR9wm3
z0$~|t3}5KU_z!f+wGB;{WFWhgx&P=AkY%ByC5BkJv@xPLE8wm%$agl}+So2I?NH;q
zN(}vry1UMjWFI*}mM!4(y^NBMoCYl_p$4E2Q@?e_&QW_XD|2>PZb7X^r!M1zwE@({
zH!Ak3cG|aZb~p$x3qTL04-!Y9!p%vkb-(JU!#D2>LJHXtCvM>50e7#jyEJLwxR3Jq
zQ?66vN@nLF*rEvt{<#5WDbo7#NTq>fbT3zMySCEO?UnZSG<6rJ#`Mxp0(-b1(a^lv
z@1c`QlJQGLCm(|(R`%Fijj8cGegS|YEx^R2<>f;aY(MDpHI*1e3U~=%JbkJ`85y2R
z3Q63I;jef0CvHaC^zBdS!s3K(j)*xlwv?_!sY$zFetP6V54^NhSqHmlevzJD991XX
z`Z4t5{mPd9ObS-t_MxGx#GzTUK`wZ6UC2i5=`JF!t8;wZVAEt;fVSFOD4ShTHpLHH
z^wZ?(I*ZQ<P=-rItwcPkS1-#t$<Cj}hQV);Iv%$3HkJi?(_%m>r)DwvJIUaqbAqRT
zPn}fzqa(+|Kk;*$jS)OvHCE+D4+@Zq@<E%}UX|sOJ_VDnLz&dmtz#Hheq4dz;V1D7
zp4Fk_NP^Nvn$AU0mfecnLekkT3P!Ij@n%Mv1bC-Z@wg4|-E24;Q)650Ph)zRnvyZl
zrKU(O*2hPfbGAv^la(e8fDK?$2pOkWKqPaI<d^y=hICZ>+zIT@9FvawD*DAQd`=bU
zmTM*e9@!;VGw;2MBE7N<02@eQlNt_W{qlrx1MC)MPAmyYn*KT$K7N~;>>=}{I&;OG
zS$=ptHMefX8VzK9JlxmCn_u8Nn}oVfilaMKq{x2x6`EO(SA`-r8d3zR;_+Cj(RX#3
z9<Hzz1X00dMKBc<oVOMd9=R`PGq`(*j<xdqEe$!q*qoZq$DOM2bO_gTzhb~u0IsQX
zJr-@V(GDZ=lKW=8MA2uYcFe`35GWyi_@30b8Qoe+nu6~H4Gx>DR-?RZ$%0S9T~?nq
zPdv_#Cr8S<O76`@1HYLW&o}%<mwQrf4gS4qRNQ0yLVerNBHiv%8*N%I?{Ae?@gOzI
zxGE!yrB%yI)+?$TG^}5~_(}rmUMqF=5U^CPI@}O)V%K{cWz<@6d?t@%>>SbQ>D1Ok
z6D>)0Q*9Hq{BQ2`UaYp;iGzP-RcmZ~iHLH=ukoC}{WZs3a-k}%aeCxfw91oWFx+25
zFVyqI%XvUWFHpn5Z_6uddGmagg(2fLBZm?JeB-bL16OE6lX~u(rn_zO+6H6#aq$5w
zmp$)TZ7wJ-KD5L#78CwmaAYKPb9466_yMh;Td`CU{||1S7`|~WSi83jv1roL##!0R
zvn`mC)Iw(AOBRe3wz`3scpL8w8VAg1KIC!nnIYkd+-k$L;E`$!zR!96l}K7X@%!QQ
zS!$}~QGoO9-guMrZD!M#pf&jXMN^X}p|xS9@ZZIfd-!$el$8xS4g($Q<HnpEObi(;
zK==;M%e$nk{KMY4&|j{#@s^EMS@w8xGa>9KNdtpO<rLNmnu~xsg|!(xA^r;!SpJg$
z`ETogz!LrqnBXVJneeTW=EC1gtKyOT|3WJMk2~EuC-o4kwUoV+je;L}X=SNm2}A$?
E0GD|~!T<mO

literal 0
HcmV?d00001

diff --git a/examples/aio-prio-percentage.fio b/examples/aio-prio-percentage.fio
new file mode 100644
index 00000000..37aec681
--- /dev/null
+++ b/examples/aio-prio-percentage.fio
@@ -0,0 +1,17 @@
+; Read a block device file at queue depth 8
+; with 20 % of the IOs using the high priority RT class
+; and the remaining IOs using the idle priority class
+[global]
+filename=/dev/sda
+direct=1
+write_lat_log=prio-run.log
+log_prio=1
+
+[randread]
+rw=randread
+bs=128k
+ioengine=libaio
+iodepth=8
+prioclass=3
+aioprio_percentage=20
+aioprioclass=1
diff --git a/examples/aio-prio-percentage.png b/examples/aio-prio-percentage.png
new file mode 100644
index 0000000000000000000000000000000000000000..012c2726dbe985569049d17d06ef83cb089cb127
GIT binary patch
literal 48752
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

literal 0
HcmV?d00001

-- 
2.31.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 00/11] Improve libaio IO priority support
  2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
                   ` (10 preceding siblings ...)
  2021-07-06  0:17 ` [PATCH 11/11] examples: add libaio priority use examples Damien Le Moal
@ 2021-07-19  3:24 ` Damien Le Moal
  2021-07-19 14:20   ` Jens Axboe
  11 siblings, 1 reply; 15+ messages in thread
From: Damien Le Moal @ 2021-07-19  3:24 UTC (permalink / raw)
  To: fio, Jens Axboe; +Cc: Bart Van Assche

On 2021/07/06 9:17, Damien Le Moal wrote:
> This series improves libaio engine support for IO priority, adding
> options to allow for mixed priority workloads to be specified more
> easily and to match the kernel supported IO priority features.
> 
> The first 3 patches are small cleanup and fixes in the manpage and
> fiograph tool.
> 
> Patch 4 and 5 introduce some helper functions to simplify the code in
> the followup patches.
> 
> Patch 6 changes the cmdprio_percentage option to allow specifying
> different percentages for reads and writes.
> 
> Patch 7 and 8 introduce the aioprioclass, aioprio and aioprio_bssplit.
> These together allow a script to specify different IO priorities for
> reads and writes of different sizes with different percentages.
> 
> Patch 9 relaxes restrictions on the cmdprio_percentage option to allow
> jobs to execute AIOs using a default priority as set with ioprio_set()
> (as the kernel supports this).
> 
> Patch 10 introduces the log_prio option to log each IO priority value,
> allowing users to do per-priority level performance analysis with
> complex workloads using many jobs.
> 
> Finally, patch 11 adds a couple of example scripts to illustrate the use
> of the new options introduced.
> 
> Comments are as always most welcome.

Hi Jens,

Any comment on this series ? We have been using this for a while now internally
and in the field to test ATA NCQ priority with good results. I am also planning
to re-use this to add support for the Command Duration Limits feature (ATA &
SCSI) using a new priority class (kernel patching cooking, but this will need
some more time as the specifications must stabilize first.

One thing that can be considered missing with this series is a full set of
per-priority level statistics (IOPS, BW, etc). But that is a major change and so
this is not talked here.

> 
> Damien Le Moal (11):
>   manpage: fix formatting
>   manpage: fix definition of prio and prioclass options
>   tools: fiograph: do not overwrite input script file
>   os: introduce ioprio_value() helper
>   options: make parsing functions available to ioengines
>   libaio,io_uring: improve cmdprio_percentage option
>   libaio: introduce aioprio and aioprioclass options
>   libaio: introduce aioprio_bssplit
>   libaio: relax cdmprio_percentage constraints
>   fio: Introduce the log_prio option
>   examples: add libaio priority use examples
> 
>  HOWTO                            |  57 +++++++--
>  backend.c                        |   1 +
>  cconv.c                          |   2 +
>  client.c                         |   2 +
>  engines/filecreate.c             |   2 +-
>  engines/filedelete.c             |   2 +-
>  engines/filestat.c               |   2 +-
>  engines/io_uring.c               |  33 +++--
>  engines/libaio.c                 | 210 ++++++++++++++++++++++++++++---
>  eta.c                            |   2 +-
>  examples/aio-prio-bssplit.fio    |  17 +++
>  examples/aio-prio-bssplit.png    | Bin 0 -> 48709 bytes
>  examples/aio-prio-percentage.fio |  17 +++
>  examples/aio-prio-percentage.png | Bin 0 -> 48752 bytes
>  fio.1                            |  76 ++++++++---
>  fio.h                            |   5 +
>  init.c                           |   4 +
>  io_u.c                           |  14 ++-
>  io_u.h                           |  10 +-
>  iolog.c                          |  45 +++++--
>  iolog.h                          |  16 ++-
>  options.c                        |  50 ++++----
>  os/os-android.h                  |  24 ++--
>  os/os-dragonfly.h                |   1 +
>  os/os-linux.h                    |  24 ++--
>  os/os.h                          |   4 +
>  server.h                         |   3 +-
>  stat.c                           |  75 +++++------
>  stat.h                           |   9 +-
>  thread_options.h                 |  20 +++
>  tools/fiograph/fiograph.conf     |   4 +-
>  tools/fiograph/fiograph.py       |   4 +-
>  32 files changed, 574 insertions(+), 161 deletions(-)
>  create mode 100644 examples/aio-prio-bssplit.fio
>  create mode 100644 examples/aio-prio-bssplit.png
>  create mode 100644 examples/aio-prio-percentage.fio
>  create mode 100644 examples/aio-prio-percentage.png
> 


-- 
Damien Le Moal
Western Digital Research


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 00/11] Improve libaio IO priority support
  2021-07-19  3:24 ` [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
@ 2021-07-19 14:20   ` Jens Axboe
  2021-08-02  5:44     ` Damien Le Moal
  0 siblings, 1 reply; 15+ messages in thread
From: Jens Axboe @ 2021-07-19 14:20 UTC (permalink / raw)
  To: Damien Le Moal, fio; +Cc: Bart Van Assche

On 7/18/21 9:24 PM, Damien Le Moal wrote:
> On 2021/07/06 9:17, Damien Le Moal wrote:
>> This series improves libaio engine support for IO priority, adding
>> options to allow for mixed priority workloads to be specified more
>> easily and to match the kernel supported IO priority features.
>>
>> The first 3 patches are small cleanup and fixes in the manpage and
>> fiograph tool.
>>
>> Patch 4 and 5 introduce some helper functions to simplify the code in
>> the followup patches.
>>
>> Patch 6 changes the cmdprio_percentage option to allow specifying
>> different percentages for reads and writes.
>>
>> Patch 7 and 8 introduce the aioprioclass, aioprio and aioprio_bssplit.
>> These together allow a script to specify different IO priorities for
>> reads and writes of different sizes with different percentages.
>>
>> Patch 9 relaxes restrictions on the cmdprio_percentage option to allow
>> jobs to execute AIOs using a default priority as set with ioprio_set()
>> (as the kernel supports this).
>>
>> Patch 10 introduces the log_prio option to log each IO priority value,
>> allowing users to do per-priority level performance analysis with
>> complex workloads using many jobs.
>>
>> Finally, patch 11 adds a couple of example scripts to illustrate the use
>> of the new options introduced.
>>
>> Comments are as always most welcome.
> 
> Hi Jens,
> 
> Any comment on this series ? We have been using this for a while now internally
> and in the field to test ATA NCQ priority with good results. I am also planning
> to re-use this to add support for the Command Duration Limits feature (ATA &
> SCSI) using a new priority class (kernel patching cooking, but this will need
> some more time as the specifications must stabilize first.
> 
> One thing that can be considered missing with this series is a full set of
> per-priority level statistics (IOPS, BW, etc). But that is a major change and so
> this is not talked here.

I'll give it a look over today. My main object would be to ensure that
aio and io_uring provide the same kind of interface, there shouldn't be
any differences there in terms of how to use them and what they do. Even
naming should be the same. Engine options exist for engine specific
options. These don't apply to all engines, but to the ones they do, they
should be interchangable. I should be able to take a job file with
ioengine=X and change it to =Y and have the priorities still work,
provided that engine Y supports it.

As far as I'm concerned, aio is legacy and I have no real interest in
adding anything that supports that, be it kernel or software.

-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 00/11] Improve libaio IO priority support
  2021-07-19 14:20   ` Jens Axboe
@ 2021-08-02  5:44     ` Damien Le Moal
  0 siblings, 0 replies; 15+ messages in thread
From: Damien Le Moal @ 2021-08-02  5:44 UTC (permalink / raw)
  To: Jens Axboe, fio; +Cc: Bart Van Assche

On 2021/07/19 23:20, Jens Axboe wrote:
> On 7/18/21 9:24 PM, Damien Le Moal wrote:
>> On 2021/07/06 9:17, Damien Le Moal wrote:
>>> This series improves libaio engine support for IO priority, adding
>>> options to allow for mixed priority workloads to be specified more
>>> easily and to match the kernel supported IO priority features.
>>>
>>> The first 3 patches are small cleanup and fixes in the manpage and
>>> fiograph tool.
>>>
>>> Patch 4 and 5 introduce some helper functions to simplify the code in
>>> the followup patches.
>>>
>>> Patch 6 changes the cmdprio_percentage option to allow specifying
>>> different percentages for reads and writes.
>>>
>>> Patch 7 and 8 introduce the aioprioclass, aioprio and aioprio_bssplit.
>>> These together allow a script to specify different IO priorities for
>>> reads and writes of different sizes with different percentages.
>>>
>>> Patch 9 relaxes restrictions on the cmdprio_percentage option to allow
>>> jobs to execute AIOs using a default priority as set with ioprio_set()
>>> (as the kernel supports this).
>>>
>>> Patch 10 introduces the log_prio option to log each IO priority value,
>>> allowing users to do per-priority level performance analysis with
>>> complex workloads using many jobs.
>>>
>>> Finally, patch 11 adds a couple of example scripts to illustrate the use
>>> of the new options introduced.
>>>
>>> Comments are as always most welcome.
>>
>> Hi Jens,
>>
>> Any comment on this series ? We have been using this for a while now internally
>> and in the field to test ATA NCQ priority with good results. I am also planning
>> to re-use this to add support for the Command Duration Limits feature (ATA &
>> SCSI) using a new priority class (kernel patching cooking, but this will need
>> some more time as the specifications must stabilize first.
>>
>> One thing that can be considered missing with this series is a full set of
>> per-priority level statistics (IOPS, BW, etc). But that is a major change and so
>> this is not talked here.
> 
> I'll give it a look over today. My main object would be to ensure that
> aio and io_uring provide the same kind of interface, there shouldn't be
> any differences there in terms of how to use them and what they do. Even
> naming should be the same. Engine options exist for engine specific
> options. These don't apply to all engines, but to the ones they do, they
> should be interchangable. I should be able to take a job file with
> ioengine=X and change it to =Y and have the priorities still work,
> provided that engine Y supports it.
> 
> As far as I'm concerned, aio is legacy and I have no real interest in
> adding anything that supports that, be it kernel or software.

OK. Let me cook a V2 to include io_uring support for the priority options.


-- 
Damien Le Moal
Western Digital Research


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2021-08-02  5:44 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-06  0:17 [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
2021-07-06  0:17 ` [PATCH 01/11] manpage: fix formatting Damien Le Moal
2021-07-06  0:17 ` [PATCH 02/11] manpage: fix definition of prio and prioclass options Damien Le Moal
2021-07-06  0:17 ` [PATCH 03/11] tools: fiograph: do not overwrite input script file Damien Le Moal
2021-07-06  0:17 ` [PATCH 04/11] os: introduce ioprio_value() helper Damien Le Moal
2021-07-06  0:17 ` [PATCH 05/11] options: make parsing functions available to ioengines Damien Le Moal
2021-07-06  0:17 ` [PATCH 06/11] libaio,io_uring: improve cmdprio_percentage option Damien Le Moal
2021-07-06  0:17 ` [PATCH 07/11] libaio: introduce aioprio and aioprioclass options Damien Le Moal
2021-07-06  0:17 ` [PATCH 08/11] libaio: introduce aioprio_bssplit Damien Le Moal
2021-07-06  0:17 ` [PATCH 09/11] libaio: relax cdmprio_percentage constraints Damien Le Moal
2021-07-06  0:17 ` [PATCH 10/11] fio: Introduce the log_prio option Damien Le Moal
2021-07-06  0:17 ` [PATCH 11/11] examples: add libaio priority use examples Damien Le Moal
2021-07-19  3:24 ` [PATCH 00/11] Improve libaio IO priority support Damien Le Moal
2021-07-19 14:20   ` Jens Axboe
2021-08-02  5:44     ` Damien Le Moal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.