From: Tvrtko Ursulin <tursulin@ursulin.net> To: igt-dev@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org Subject: [PATCH i-g-t 5/6] intel-gpu-top: Add queue depths and load average Date: Wed, 6 Jun 2018 13:49:06 +0100 [thread overview] Message-ID: <20180606124907.13139-6-tvrtko.ursulin@linux.intel.com> (raw) In-Reply-To: <20180606124907.13139-1-tvrtko.ursulin@linux.intel.com> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com> With the driver now exporting various request queue depths for each engine, we can display this information here. Both as raw counters, and by adding a load average like metrics composed from number of runnable and running requests in a given time period. 1s, 30s and 5m periods are used for load average. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> --- tools/Makefile.am | 2 +- tools/intel_gpu_top.c | 122 +++++++++++++++++++++++++++++++++++++----- tools/meson.build | 2 +- 3 files changed, 110 insertions(+), 16 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index a0b016ddd7ff..e1d5f1bdc89a 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -28,7 +28,7 @@ intel_aubdump_la_LDFLAGS = -module -avoid-version -no-undefined intel_aubdump_la_SOURCES = aubdump.c intel_aubdump_la_LIBADD = $(top_builddir)/lib/libintel_tools.la -ldl -intel_gpu_top_LDADD = $(top_builddir)/lib/libigt_perf.la +intel_gpu_top_LDADD = $(top_builddir)/lib/libigt_perf.la -lm bin_SCRIPTS = intel_aubdump CLEANFILES = $(bin_SCRIPTS) diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index b923c3cfbe97..8990ef17b771 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -56,6 +56,10 @@ struct pmu_counter { struct pmu_pair val; }; +#define NUM_QUEUES (3) + +#define NUM_LOADS (3) + struct engine { const char *name; const char *display_name; @@ -65,9 +69,13 @@ struct engine { unsigned int num_counters; + double qd[3]; + double load_avg[NUM_LOADS]; + struct pmu_counter busy; struct pmu_counter wait; struct pmu_counter sema; + struct pmu_counter queue[NUM_QUEUES]; }; struct engines { @@ -95,6 +103,11 @@ struct engines { struct pmu_counter imc_reads; struct pmu_counter imc_writes; + double qd_scale; + + double load_exp[NUM_LOADS]; + double load_avg[NUM_LOADS]; + struct engine engine; }; @@ -320,6 +333,13 @@ static double filename_to_double(const char *filename) return v; } +#define I915_EVENT "/sys/devices/i915/events/" + +static double i915_qd_scale(void) +{ + return filename_to_double(I915_EVENT "rcs0-queued.scale"); +} + #define RAPL_ROOT "/sys/devices/power/" #define RAPL_EVENT "/sys/devices/power/events/" @@ -453,6 +473,8 @@ static int pmu_init(struct engines *engines) engines->rc6.config = I915_PMU_RC6_RESIDENCY; _open_pmu(engines->num_counters, &engines->rc6, engines->fd); + engines->qd_scale = i915_qd_scale(); + for (i = 0; i < engines->num_engines; i++) { struct engine *engine = engine_ptr(engines, i); struct { @@ -462,6 +484,9 @@ static int pmu_init(struct engines *engines) { .pmu = &engine->busy, .counter = "busy" }, { .pmu = &engine->wait, .counter = "wait" }, { .pmu = &engine->sema, .counter = "sema" }, + { .pmu = &engine->queue[0], .counter = "queued" }, + { .pmu = &engine->queue[1], .counter = "runnable" }, + { .pmu = &engine->queue[2], .counter = "running" }, { .pmu = NULL, .counter = NULL }, }; @@ -576,12 +601,11 @@ static void fill_str(char *buf, unsigned int bufsz, char c, unsigned int num) *buf = 0; } -static void pmu_calc(struct pmu_counter *cnt, - char *buf, unsigned int bufsz, - unsigned int width, unsigned width_dec, - double d, double t, double s) +static void _pmu_calc(struct pmu_counter *cnt, + char *buf, unsigned int bufsz, + unsigned int width, unsigned width_dec, + double val) { - double val; int len; assert(bufsz >= (width + width_dec + 1)); @@ -591,8 +615,6 @@ static void pmu_calc(struct pmu_counter *cnt, return; } - val = __pmu_calc(&cnt->val, d, t, s); - len = snprintf(buf, bufsz, "%*.*f", width + width_dec, width_dec, val); if (len < 0 || len == bufsz) { fill_str(buf, bufsz, 'X', width + width_dec); @@ -600,6 +622,16 @@ static void pmu_calc(struct pmu_counter *cnt, } } +static void pmu_calc(struct pmu_counter *cnt, + char *buf, unsigned int bufsz, + unsigned int width, unsigned width_dec, + double d, double t, double s) +{ + double val = __pmu_calc(&cnt->val, d, t, s); + + _pmu_calc(cnt, buf, bufsz, width, width_dec, val); +} + static uint64_t __pmu_read_single(int fd, uint64_t *ts) { uint64_t data[2] = { }; @@ -658,10 +690,14 @@ static void pmu_sample(struct engines *engines) for (i = 0; i < engines->num_engines; i++) { struct engine *engine = engine_ptr(engines, i); + unsigned int j; update_sample(&engine->busy, val); update_sample(&engine->sema, val); update_sample(&engine->wait, val); + + for (j = 0; j < NUM_QUEUES; j++) + update_sample(&engine->queue[j], val); } } @@ -702,12 +738,19 @@ usage(const char *appname) appname, DEFAULT_PERIOD_MS); } +static double update_load(double load, double exp, double val) +{ + return val + exp * (load - val); +} + int main(int argc, char **argv) { unsigned int period_us = DEFAULT_PERIOD_MS * 1000; + const double load_period[NUM_LOADS] = { 1.0, 30.0, 900.0 }; int con_w = -1, con_h = -1; struct engines *engines; unsigned int i; + double period; int ret, ch; /* Parse options */ @@ -741,10 +784,15 @@ int main(int argc, char **argv) return 1; } + /* Load average setup. */ + period = (double)period_us / 1e6; + for (i = 0; i < NUM_LOADS; i++) + engines->load_exp[i] = exp(-period / load_period[i]); + pmu_sample(engines); for (;;) { - double t; + double t, qd = 0; #define BUFSZ 16 char freq[BUFSZ]; char fact[BUFSZ]; @@ -754,6 +802,7 @@ int main(int argc, char **argv) char reads[BUFSZ]; char writes[BUFSZ]; struct winsize ws; + unsigned int j; int lines = 0; /* Update terminal size. */ @@ -778,8 +827,44 @@ int main(int argc, char **argv) pmu_calc(&engines->imc_writes, writes, BUFSZ, 6, 0, 1.0, t, engines->imc_writes_scale); + for (i = 0; i < engines->num_engines; i++) { + struct engine *engine = engine_ptr(engines, i); + + if (!engine->num_counters) + continue; + + for (j = 0; j < NUM_QUEUES; j++) { + if (!engine->queue[j].present) + continue; + + engine->qd[j] = + __pmu_calc(&engine->queue[j].val, 1, t, + engines->qd_scale); + } + + qd += engine->qd[1] + engine->qd[2]; + + for (j = 0; j < NUM_LOADS; j++) { + engine->load_avg[j] = + update_load(engine->load_avg[j], + engines->load_exp[j], + engine->qd[1] + + engine->qd[2]); + } + } + + for (j = 0; j < NUM_LOADS; j++) { + engines->load_avg[j] = + update_load(engines->load_avg[j], + engines->load_exp[j], + qd); + } + if (lines++ < con_h) - printf("intel-gpu-top - %s/%s MHz; %s%% RC6; %s %s; %s irqs/s\n", + printf("intel-gpu-top - load avg %5.2f, %5.2f, %5.2f; %s/%s MHz; %s%% RC6; %s %s; %s irqs/s\n", + engines->load_avg[0], + engines->load_avg[1], + engines->load_avg[2], fact, freq, rc6, power, engines->rapl_unit, irq); if (lines++ < con_h) @@ -803,7 +888,7 @@ int main(int argc, char **argv) if (engine->num_counters && lines < con_h) { const char *a = " ENGINE BUSY "; - const char *b = " MI_SEMA MI_WAIT"; + const char *b = "Q r R MI_SEMA MI_WAIT"; printf("\033[7m%s%*s%s\033[0m\n", a, @@ -817,6 +902,7 @@ int main(int argc, char **argv) for (i = 0; i < engines->num_engines && lines < con_h; i++) { struct engine *engine = engine_ptr(engines, i); unsigned int max_w = con_w - 1; + char qdbuf[NUM_LOADS][BUFSZ]; unsigned int len; char sema[BUFSZ]; char wait[BUFSZ]; @@ -827,14 +913,22 @@ int main(int argc, char **argv) if (!engine->num_counters) continue; + for (j = 0; j < NUM_QUEUES; j++) + _pmu_calc(&engine->queue[j], qdbuf[j], BUFSZ, + 3, 0, engine->qd[j]); + pmu_calc(&engine->sema, sema, BUFSZ, 3, 0, 1e9, t, 100); pmu_calc(&engine->wait, wait, BUFSZ, 3, 0, 1e9, t, 100); - len = snprintf(buf, sizeof(buf), " %s%% %s%%", + + len = snprintf(buf, sizeof(buf), + " %s %s %s %s%% %s%%", + qdbuf[0], qdbuf[1], qdbuf[2], sema, wait); - pmu_calc(&engine->busy, busy, BUFSZ, 6, 2, 1e9, t, - 100); - len += printf("%16s %s%% ", engine->display_name, busy); + pmu_calc(&engine->busy, busy, BUFSZ, 6, 2, 1e9, t, 100); + + len += printf("%16s %s%% ", + engine->display_name, busy); val = __pmu_calc(&engine->busy.val, 1e9, t, 100); print_percentage_bar(val, max_w - len); diff --git a/tools/meson.build b/tools/meson.build index 8ed1ccf48d6e..18abb396c56f 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -119,7 +119,7 @@ shared_library('intel_aubdump', 'aubdump.c', executable('intel_gpu_top', 'intel_gpu_top.c', install : true, install_rpath : rpathdir, - dependencies : tool_deps + [ lib_igt_perf ]) + dependencies : tool_deps + [ lib_igt_perf, math ]) conf_data = configuration_data() conf_data.set('prefix', prefix) -- 2.17.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
WARNING: multiple messages have this Message-ID (diff)
From: Tvrtko Ursulin <tursulin@ursulin.net> To: igt-dev@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Tvrtko Ursulin <tvrtko.ursulin@intel.com> Subject: [igt-dev] [PATCH i-g-t 5/6] intel-gpu-top: Add queue depths and load average Date: Wed, 6 Jun 2018 13:49:06 +0100 [thread overview] Message-ID: <20180606124907.13139-6-tvrtko.ursulin@linux.intel.com> (raw) In-Reply-To: <20180606124907.13139-1-tvrtko.ursulin@linux.intel.com> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com> With the driver now exporting various request queue depths for each engine, we can display this information here. Both as raw counters, and by adding a load average like metrics composed from number of runnable and running requests in a given time period. 1s, 30s and 5m periods are used for load average. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> --- tools/Makefile.am | 2 +- tools/intel_gpu_top.c | 122 +++++++++++++++++++++++++++++++++++++----- tools/meson.build | 2 +- 3 files changed, 110 insertions(+), 16 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index a0b016ddd7ff..e1d5f1bdc89a 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -28,7 +28,7 @@ intel_aubdump_la_LDFLAGS = -module -avoid-version -no-undefined intel_aubdump_la_SOURCES = aubdump.c intel_aubdump_la_LIBADD = $(top_builddir)/lib/libintel_tools.la -ldl -intel_gpu_top_LDADD = $(top_builddir)/lib/libigt_perf.la +intel_gpu_top_LDADD = $(top_builddir)/lib/libigt_perf.la -lm bin_SCRIPTS = intel_aubdump CLEANFILES = $(bin_SCRIPTS) diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index b923c3cfbe97..8990ef17b771 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -56,6 +56,10 @@ struct pmu_counter { struct pmu_pair val; }; +#define NUM_QUEUES (3) + +#define NUM_LOADS (3) + struct engine { const char *name; const char *display_name; @@ -65,9 +69,13 @@ struct engine { unsigned int num_counters; + double qd[3]; + double load_avg[NUM_LOADS]; + struct pmu_counter busy; struct pmu_counter wait; struct pmu_counter sema; + struct pmu_counter queue[NUM_QUEUES]; }; struct engines { @@ -95,6 +103,11 @@ struct engines { struct pmu_counter imc_reads; struct pmu_counter imc_writes; + double qd_scale; + + double load_exp[NUM_LOADS]; + double load_avg[NUM_LOADS]; + struct engine engine; }; @@ -320,6 +333,13 @@ static double filename_to_double(const char *filename) return v; } +#define I915_EVENT "/sys/devices/i915/events/" + +static double i915_qd_scale(void) +{ + return filename_to_double(I915_EVENT "rcs0-queued.scale"); +} + #define RAPL_ROOT "/sys/devices/power/" #define RAPL_EVENT "/sys/devices/power/events/" @@ -453,6 +473,8 @@ static int pmu_init(struct engines *engines) engines->rc6.config = I915_PMU_RC6_RESIDENCY; _open_pmu(engines->num_counters, &engines->rc6, engines->fd); + engines->qd_scale = i915_qd_scale(); + for (i = 0; i < engines->num_engines; i++) { struct engine *engine = engine_ptr(engines, i); struct { @@ -462,6 +484,9 @@ static int pmu_init(struct engines *engines) { .pmu = &engine->busy, .counter = "busy" }, { .pmu = &engine->wait, .counter = "wait" }, { .pmu = &engine->sema, .counter = "sema" }, + { .pmu = &engine->queue[0], .counter = "queued" }, + { .pmu = &engine->queue[1], .counter = "runnable" }, + { .pmu = &engine->queue[2], .counter = "running" }, { .pmu = NULL, .counter = NULL }, }; @@ -576,12 +601,11 @@ static void fill_str(char *buf, unsigned int bufsz, char c, unsigned int num) *buf = 0; } -static void pmu_calc(struct pmu_counter *cnt, - char *buf, unsigned int bufsz, - unsigned int width, unsigned width_dec, - double d, double t, double s) +static void _pmu_calc(struct pmu_counter *cnt, + char *buf, unsigned int bufsz, + unsigned int width, unsigned width_dec, + double val) { - double val; int len; assert(bufsz >= (width + width_dec + 1)); @@ -591,8 +615,6 @@ static void pmu_calc(struct pmu_counter *cnt, return; } - val = __pmu_calc(&cnt->val, d, t, s); - len = snprintf(buf, bufsz, "%*.*f", width + width_dec, width_dec, val); if (len < 0 || len == bufsz) { fill_str(buf, bufsz, 'X', width + width_dec); @@ -600,6 +622,16 @@ static void pmu_calc(struct pmu_counter *cnt, } } +static void pmu_calc(struct pmu_counter *cnt, + char *buf, unsigned int bufsz, + unsigned int width, unsigned width_dec, + double d, double t, double s) +{ + double val = __pmu_calc(&cnt->val, d, t, s); + + _pmu_calc(cnt, buf, bufsz, width, width_dec, val); +} + static uint64_t __pmu_read_single(int fd, uint64_t *ts) { uint64_t data[2] = { }; @@ -658,10 +690,14 @@ static void pmu_sample(struct engines *engines) for (i = 0; i < engines->num_engines; i++) { struct engine *engine = engine_ptr(engines, i); + unsigned int j; update_sample(&engine->busy, val); update_sample(&engine->sema, val); update_sample(&engine->wait, val); + + for (j = 0; j < NUM_QUEUES; j++) + update_sample(&engine->queue[j], val); } } @@ -702,12 +738,19 @@ usage(const char *appname) appname, DEFAULT_PERIOD_MS); } +static double update_load(double load, double exp, double val) +{ + return val + exp * (load - val); +} + int main(int argc, char **argv) { unsigned int period_us = DEFAULT_PERIOD_MS * 1000; + const double load_period[NUM_LOADS] = { 1.0, 30.0, 900.0 }; int con_w = -1, con_h = -1; struct engines *engines; unsigned int i; + double period; int ret, ch; /* Parse options */ @@ -741,10 +784,15 @@ int main(int argc, char **argv) return 1; } + /* Load average setup. */ + period = (double)period_us / 1e6; + for (i = 0; i < NUM_LOADS; i++) + engines->load_exp[i] = exp(-period / load_period[i]); + pmu_sample(engines); for (;;) { - double t; + double t, qd = 0; #define BUFSZ 16 char freq[BUFSZ]; char fact[BUFSZ]; @@ -754,6 +802,7 @@ int main(int argc, char **argv) char reads[BUFSZ]; char writes[BUFSZ]; struct winsize ws; + unsigned int j; int lines = 0; /* Update terminal size. */ @@ -778,8 +827,44 @@ int main(int argc, char **argv) pmu_calc(&engines->imc_writes, writes, BUFSZ, 6, 0, 1.0, t, engines->imc_writes_scale); + for (i = 0; i < engines->num_engines; i++) { + struct engine *engine = engine_ptr(engines, i); + + if (!engine->num_counters) + continue; + + for (j = 0; j < NUM_QUEUES; j++) { + if (!engine->queue[j].present) + continue; + + engine->qd[j] = + __pmu_calc(&engine->queue[j].val, 1, t, + engines->qd_scale); + } + + qd += engine->qd[1] + engine->qd[2]; + + for (j = 0; j < NUM_LOADS; j++) { + engine->load_avg[j] = + update_load(engine->load_avg[j], + engines->load_exp[j], + engine->qd[1] + + engine->qd[2]); + } + } + + for (j = 0; j < NUM_LOADS; j++) { + engines->load_avg[j] = + update_load(engines->load_avg[j], + engines->load_exp[j], + qd); + } + if (lines++ < con_h) - printf("intel-gpu-top - %s/%s MHz; %s%% RC6; %s %s; %s irqs/s\n", + printf("intel-gpu-top - load avg %5.2f, %5.2f, %5.2f; %s/%s MHz; %s%% RC6; %s %s; %s irqs/s\n", + engines->load_avg[0], + engines->load_avg[1], + engines->load_avg[2], fact, freq, rc6, power, engines->rapl_unit, irq); if (lines++ < con_h) @@ -803,7 +888,7 @@ int main(int argc, char **argv) if (engine->num_counters && lines < con_h) { const char *a = " ENGINE BUSY "; - const char *b = " MI_SEMA MI_WAIT"; + const char *b = "Q r R MI_SEMA MI_WAIT"; printf("\033[7m%s%*s%s\033[0m\n", a, @@ -817,6 +902,7 @@ int main(int argc, char **argv) for (i = 0; i < engines->num_engines && lines < con_h; i++) { struct engine *engine = engine_ptr(engines, i); unsigned int max_w = con_w - 1; + char qdbuf[NUM_LOADS][BUFSZ]; unsigned int len; char sema[BUFSZ]; char wait[BUFSZ]; @@ -827,14 +913,22 @@ int main(int argc, char **argv) if (!engine->num_counters) continue; + for (j = 0; j < NUM_QUEUES; j++) + _pmu_calc(&engine->queue[j], qdbuf[j], BUFSZ, + 3, 0, engine->qd[j]); + pmu_calc(&engine->sema, sema, BUFSZ, 3, 0, 1e9, t, 100); pmu_calc(&engine->wait, wait, BUFSZ, 3, 0, 1e9, t, 100); - len = snprintf(buf, sizeof(buf), " %s%% %s%%", + + len = snprintf(buf, sizeof(buf), + " %s %s %s %s%% %s%%", + qdbuf[0], qdbuf[1], qdbuf[2], sema, wait); - pmu_calc(&engine->busy, busy, BUFSZ, 6, 2, 1e9, t, - 100); - len += printf("%16s %s%% ", engine->display_name, busy); + pmu_calc(&engine->busy, busy, BUFSZ, 6, 2, 1e9, t, 100); + + len += printf("%16s %s%% ", + engine->display_name, busy); val = __pmu_calc(&engine->busy.val, 1e9, t, 100); print_percentage_bar(val, max_w - len); diff --git a/tools/meson.build b/tools/meson.build index 8ed1ccf48d6e..18abb396c56f 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -119,7 +119,7 @@ shared_library('intel_aubdump', 'aubdump.c', executable('intel_gpu_top', 'intel_gpu_top.c', install : true, install_rpath : rpathdir, - dependencies : tool_deps + [ lib_igt_perf ]) + dependencies : tool_deps + [ lib_igt_perf, math ]) conf_data = configuration_data() conf_data.set('prefix', prefix) -- 2.17.1 _______________________________________________ igt-dev mailing list igt-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/igt-dev
next prev parent reply other threads:[~2018-06-06 12:49 UTC|newest] Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-06-06 12:49 [PATCH i-g-t 0/6] Queued/runnable/running engine stats Tvrtko Ursulin 2018-06-06 12:49 ` [igt-dev] " Tvrtko Ursulin 2018-06-06 12:49 ` [PATCH i-g-t 1/6] include: i915 uAPI headers Tvrtko Ursulin 2018-06-06 12:49 ` [igt-dev] " Tvrtko Ursulin 2018-06-06 12:49 ` [PATCH i-g-t 2/6] intel-gpu-overlay: Add engine queue stats Tvrtko Ursulin 2018-06-06 12:49 ` [igt-dev] " Tvrtko Ursulin 2018-06-06 12:49 ` [PATCH i-g-t 3/6] intel-gpu-overlay: Show 1s, 30s and 15m GPU load Tvrtko Ursulin 2018-06-06 12:49 ` [igt-dev] " Tvrtko Ursulin 2018-06-06 12:49 ` [PATCH i-g-t 4/6] tests/perf_pmu: Add tests for engine queued/runnable/running stats Tvrtko Ursulin 2018-06-06 12:49 ` [igt-dev] " Tvrtko Ursulin 2018-06-06 12:49 ` Tvrtko Ursulin [this message] 2018-06-06 12:49 ` [igt-dev] [PATCH i-g-t 5/6] intel-gpu-top: Add queue depths and load average Tvrtko Ursulin 2018-06-06 12:49 ` [PATCH i-g-t 6/6] tests/i915_query: Engine queues tests Tvrtko Ursulin 2018-06-06 12:49 ` [igt-dev] " Tvrtko Ursulin 2018-06-06 14:33 ` Lionel Landwerlin 2018-06-06 14:33 ` [igt-dev] [Intel-gfx] " Lionel Landwerlin 2018-06-08 10:02 ` Tvrtko Ursulin 2018-06-08 10:02 ` [igt-dev] [Intel-gfx] " Tvrtko Ursulin 2018-06-08 10:13 ` Lionel Landwerlin 2018-06-08 10:13 ` [igt-dev] [Intel-gfx] " Lionel Landwerlin 2018-06-06 14:33 ` [igt-dev] ✗ Fi.CI.BAT: failure for Queued/runnable/running engine stats (rev3) Patchwork
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180606124907.13139-6-tvrtko.ursulin@linux.intel.com \ --to=tursulin@ursulin.net \ --cc=igt-dev@lists.freedesktop.org \ --cc=intel-gfx@lists.freedesktop.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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.