From: Jeevan B <jeevan.b@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: mohammed.thasleem@intel.com, Jeevan B <jeevan.b@intel.com>
Subject: [PATCH i-g-t] lib/igt_pm: Move DC State Counter Functions to common library
Date: Tue, 27 Jan 2026 12:04:32 +0530 [thread overview]
Message-ID: <20260127063432.183096-1-jeevan.b@intel.com> (raw)
Move DC counter utility functions from tests/intel/kms_pm_dc.c
to lib/igt_pm.c for reuse across other tests.
v2: Add 'igt_' prefix before all functions. (Thasleem)
Signed-off-by: Jeevan B <jeevan.b@intel.com>
---
lib/igt_pm.c | 169 ++++++++++++++++++++++++++++++++++++++++
lib/igt_pm.h | 15 ++++
tests/intel/kms_pm_dc.c | 167 ++++++---------------------------------
3 files changed, 207 insertions(+), 144 deletions(-)
diff --git a/lib/igt_pm.c b/lib/igt_pm.c
index 1ffcdcef3..cc82e2134 100644
--- a/lib/igt_pm.c
+++ b/lib/igt_pm.c
@@ -1543,3 +1543,172 @@ void igt_pm_dpms_toggle(igt_output_t *output)
DRM_MODE_DPMS_ON);
igt_assert(igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_ACTIVE));
}
+
+/**
+ * igt_get_dc_counter:
+ * @dc_data: String containing DC counter data in format
+ *
+ * Returns the counter value as uint32_t
+ */
+uint32_t igt_get_dc_counter(char *dc_data)
+{
+ char *e;
+ long ret;
+ char *s = strchr(dc_data, ':');
+
+ igt_assert(s);
+ s++;
+ ret = strtol(s, &e, 10);
+ igt_assert(((ret != LONG_MIN && ret != LONG_MAX) || errno != ERANGE) &&
+ e > s && *e == '\n' && ret >= 0);
+ return ret;
+}
+
+/**
+ * igt_support_dc6:
+ * @debugfs_fd: DRM file descriptor
+ *
+ * Returns true if DC6 is supported.
+ */
+bool igt_support_dc6(int debugfs_fd)
+{
+ char buf[4096];
+
+ igt_debugfs_simple_read(debugfs_fd, "i915_dmc_info",
+ buf, sizeof(buf));
+ return strstr(buf, "DC5 -> DC6 count");
+}
+
+/**
+ * igt_get_dc6_counter:Locate DC6 counter string in debugfs buffer
+ * @buf: Buffer containing i915_dmc_info debugfs output
+ *
+ * Searches for DC6 counter information in the DMC info buffer.
+ */
+char *igt_get_dc6_counter(const char *buf)
+{
+ char *str;
+
+ str = strstr(buf, "DC5 -> DC6 count");
+ if (!str)
+ str = strstr(buf, "DC5 -> DC6 allowed count");
+
+ return str;
+}
+
+/**
+ * igt_read_dc_counter:
+ * @debugfs_fd: DRM file descriptor
+ * @dc_flag: DC state flag (CHECK_DC5, CHECK_DC6, or CHECK_DC3CO)
+ *
+ * Returns current counter value for the specified DC state
+ */
+uint32_t igt_read_dc_counter(uint32_t debugfs_fd, int dc_flag)
+{
+ char buf[4096];
+ char *str;
+
+ igt_debugfs_simple_read(debugfs_fd, "i915_dmc_info", buf, sizeof(buf));
+
+ if (dc_flag & CHECK_DC5) {
+ str = strstr(buf, "DC3 -> DC5 count");
+ igt_assert_f(str, "DC5 counter is not available\n");
+ } else if (dc_flag & CHECK_DC6) {
+ str = igt_get_dc6_counter(buf);
+ igt_assert_f(str, "No DC6 counter available\n");
+ } else if (dc_flag & CHECK_DC3CO) {
+ str = strstr(buf, "DC3CO count");
+ igt_assert_f(str, "DC3CO counter is not available\n");
+ } else {
+ igt_assert(!"reached");
+ str = NULL;
+ }
+
+ return igt_get_dc_counter(str);
+}
+
+/**
+ * igt_dc_state_wait_entrytry:
+ * @debugfs_fd: DRM file descriptor
+ * @dc_flag: DC state flag
+ * @prev_dc_count: Previous counter value to compare against
+ *
+ * Returns true if DC state entry detected within timeout, false otherwise
+ */
+bool igt_dc_state_wait_entrytry(int debugfs_fd, int dc_flag, int prev_dc_count)
+{
+ return igt_wait(igt_read_dc_counter(debugfs_fd, dc_flag) >
+ prev_dc_count, 3000, 100);
+}
+
+/**
+ * igt_dc_state_namee:
+ * @dc_flag: DC state flag
+ *
+ * Converts DC state flag constants to readable string names
+ */
+const char *igt_dc_state_namee(int dc_flag)
+{
+ if (dc_flag & CHECK_DC3CO)
+ return "DC3CO";
+ else if (dc_flag & CHECK_DC5)
+ return "DC5";
+ else
+ return "DC6";
+}
+
+/**
+ * igt_require_dc_counter:
+ * @debugfs_fd: File descriptor for the debugfs
+ * @dc_flag: DC counter type to check (CHECK_DC3CO, CHECK_DC5,
+ * or CHECK_DC6)
+ *
+ * Skips the current test if the requested DC counter is not available
+ * on the system.
+ */
+void igt_require_dc_counter(int debugfs_fd, int dc_flag)
+{
+ char *str;
+ char buf[4096];
+
+ igt_debugfs_simple_read(debugfs_fd, "i915_dmc_info",
+ buf, sizeof(buf));
+
+ switch (dc_flag) {
+ case CHECK_DC3CO:
+ igt_skip_on_f(!strstr(buf, "DC3CO count"),
+ "DC3CO counter is not available\n");
+ break;
+ case CHECK_DC5:
+ igt_skip_on_f(!strstr(buf, "DC3 -> DC5 count"),
+ "DC5 counter is not available\n");
+ break;
+ case CHECK_DC6:
+ str = igt_get_dc6_counter(buf);
+ igt_skip_on_f(!str, "No DC6 counter available\n");
+ break;
+ default:
+ igt_assert_f(0, "Unknown DC counter %d\n", dc_flag);
+ }
+}
+
+/**
+ * igt_read_pkgc_counter:
+ * @debugfs_root_fd: File descriptor for the debugfs
+ *
+ * Returns PC10 counter value.
+ */
+unsigned int igt_read_pkgc_counter(int debugfs_root_fd)
+{
+ char buf[4096];
+ char *str;
+ int len;
+
+ len = igt_sysfs_read(debugfs_root_fd, PACKAGE_CSTATE_PATH, buf, sizeof(buf) - 1);
+ igt_skip_on_f(len < 0, "PKGC state file not found\n");
+ buf[len] = '\0';
+ str = strstr(buf, "Package C10");
+ igt_skip_on_f(!str, "PKGC10 is not supported.\n");
+
+ return igt_get_dc_counter(str);
+}
diff --git a/lib/igt_pm.h b/lib/igt_pm.h
index e931e51af..1930b3255 100644
--- a/lib/igt_pm.h
+++ b/lib/igt_pm.h
@@ -29,6 +29,13 @@
#include "igt_kms.h"
+#define PACKAGE_CSTATE_PATH "pmc_core/package_cstate_show"
+
+/* DC State Flags */
+#define CHECK_DC5 (1 << 0)
+#define CHECK_DC6 (1 << 1)
+#define CHECK_DC3CO (1 << 2)
+
void igt_pm_enable_audio_runtime_pm(void);
void igt_pm_enable_sata_link_power_management(void);
void igt_pm_restore_sata_link_power_management(void);
@@ -99,5 +106,13 @@ int igt_pm_get_runtime_usage(struct pci_device *pci_dev);
void igt_pm_ignore_slpc_efficient_freq(int i915, int gtfd, bool val);
bool igt_has_pci_pm_capability(struct pci_device *pci_dev);
void igt_pm_dpms_toggle(igt_output_t *output);
+uint32_t igt_get_dc_counter(char *dc_data);
+bool igt_support_dc6(int debugfs_fd);
+char *igt_get_dc6_counter(const char *buf);
+uint32_t igt_read_dc_counter(uint32_t debugfs_fd, int dc_flag);
+bool igt_dc_state_wait_entrytry(int debugfs_fd, int dc_flag, int prev_dc_count);
+const char *igt_dc_state_namee(int dc_flag);
+void igt_require_dc_counter(int debugfs_fd, int dc_flag);
+unsigned int igt_read_pkgc_counter(int debugfs_root_fd);
#endif /* IGT_PM_H */
diff --git a/tests/intel/kms_pm_dc.c b/tests/intel/kms_pm_dc.c
index 4babf1341..81e11c41d 100644
--- a/tests/intel/kms_pm_dc.c
+++ b/tests/intel/kms_pm_dc.c
@@ -79,15 +79,9 @@
* Description: This test validates display engine entry to DC5 state while PSR is active on Pipe B
*/
-/* DC State Flags */
-#define CHECK_DC5 (1 << 0)
-#define CHECK_DC6 (1 << 1)
-#define CHECK_DC3CO (1 << 2)
-
#define PWR_DOMAIN_INFO "i915_power_domain_info"
#define RPM_STATUS "i915_runtime_pm_status"
#define KMS_HELPER "/sys/module/drm_kms_helper/parameters/"
-#define PACKAGE_CSTATE_PATH "pmc_core/package_cstate_show"
#define KMS_POLL_DISABLE 0
#define DC9_RESETS_DC_COUNTERS(devid) (!(IS_DG1(devid) || IS_DG2(devid) || intel_display_ver(devid) >= 14))
#define SEC 1
@@ -116,7 +110,6 @@ typedef struct {
bool runtime_suspend_disabled;
} data_t;
-static bool dc_state_wait_entry(int drm_fd, int dc_flag, int prev_dc_count);
static void check_dc_counter(data_t *data, int dc_flag, uint32_t prev_dc_count);
static void set_output_on_pipe_b(data_t *data)
@@ -262,81 +255,17 @@ static void create_color_fb(data_t *data, igt_fb_t *fb, color_t *fb_color)
paint_rectangles(data, data->mode, fb_color, fb);
}
-static uint32_t get_dc_counter(char *dc_data)
-{
- char *e;
- long ret;
- char *s = strchr(dc_data, ':');
-
- igt_assert(s);
- s++;
- ret = strtol(s, &e, 10);
- igt_assert(((ret != LONG_MIN && ret != LONG_MAX) || errno != ERANGE) && e > s && *e == '\n' && ret >= 0);
- return ret;
-}
-
-static char *get_dc6_counter(const char *buf)
-{
- char *str;
-
- str = strstr(buf, "DC5 -> DC6 count");
- if (!str)
- str = strstr(buf, "DC5 -> DC6 allowed count");
-
- return str;
-}
-
-static uint32_t read_dc_counter(uint32_t debugfs_fd, int dc_flag)
-{
- char buf[4096];
- char *str;
-
- igt_debugfs_simple_read(debugfs_fd, "i915_dmc_info", buf, sizeof(buf));
-
- if (dc_flag & CHECK_DC5) {
- str = strstr(buf, "DC3 -> DC5 count");
- igt_assert_f(str, "DC5 counter is not available\n");
- } else if (dc_flag & CHECK_DC6) {
- str = get_dc6_counter(buf);
- igt_assert_f(str, "No DC6 counter available\n");
- } else if (dc_flag & CHECK_DC3CO) {
- str = strstr(buf, "DC3CO count");
- igt_assert_f(str, "DC3CO counter is not available\n");
- } else {
- igt_assert(!"reached");
- str = NULL;
- }
-
- return get_dc_counter(str);
-}
-
-static bool dc_state_wait_entry(int debugfs_fd, int dc_flag, int prev_dc_count)
-{
- return igt_wait(read_dc_counter(debugfs_fd, dc_flag) >
- prev_dc_count, 3000, 100);
-}
-
-static const char *dc_state_name(int dc_flag)
-{
- if (dc_flag & CHECK_DC3CO)
- return "DC3CO";
- else if (dc_flag & CHECK_DC5)
- return "DC5";
- else
- return "DC6";
-}
-
static void check_dc_counter(data_t *data, int dc_flag, uint32_t prev_dc_count)
{
- igt_assert_f(dc_state_wait_entry(data->debugfs_fd, dc_flag, prev_dc_count),
- "%s state is not achieved\n%s:\n%s\n", dc_state_name(dc_flag), PWR_DOMAIN_INFO,
+ igt_assert_f(igt_dc_state_wait_entrytry(data->debugfs_fd, dc_flag, prev_dc_count),
+ "%s state is not achieved\n%s:\n%s\n", igt_dc_state_namee(dc_flag), PWR_DOMAIN_INFO,
data->debugfs_dump = igt_sysfs_get(data->debugfs_fd, PWR_DOMAIN_INFO));
}
static void check_dc_counter_negative(data_t *data, int dc_flag, uint32_t prev_dc_count)
{
- igt_assert_f(!dc_state_wait_entry(data->debugfs_fd, dc_flag, prev_dc_count),
- "%s state is achieved\n%s:\n%s\n", dc_state_name(dc_flag), PWR_DOMAIN_INFO,
+ igt_assert_f(!igt_dc_state_wait_entrytry(data->debugfs_fd, dc_flag, prev_dc_count),
+ "%s state is achieved\n%s:\n%s\n", igt_dc_state_namee(dc_flag), PWR_DOMAIN_INFO,
data->debugfs_dump = igt_sysfs_get(data->debugfs_fd, PWR_DOMAIN_INFO));
}
@@ -368,7 +297,7 @@ static void check_dc3co_with_videoplayback_like_load(data_t *data)
primary = igt_output_get_plane_type(data->output,
DRM_PLANE_TYPE_PRIMARY);
igt_plane_set_fb(primary, NULL);
- dc3co_prev_cnt = read_dc_counter(data->debugfs_fd, CHECK_DC3CO);
+ dc3co_prev_cnt = igt_read_dc_counter(data->debugfs_fd, CHECK_DC3CO);
/* Calculate delay to generate idle frame in usec*/
delay = 1.5 * ((1000 * 1000) / data->mode->vrefresh);
@@ -383,36 +312,10 @@ static void check_dc3co_with_videoplayback_like_load(data_t *data)
usleep(delay);
}
- igt_require_f(dc_state_wait_entry(data->debugfs_fd,
+ igt_require_f(igt_dc_state_wait_entrytry(data->debugfs_fd,
CHECK_DC3CO, dc3co_prev_cnt), "dc3co-vpb-simulation not enabled\n");
}
-static void require_dc_counter(int debugfs_fd, int dc_flag)
-{
- char *str;
- char buf[4096];
-
- igt_debugfs_simple_read(debugfs_fd, "i915_dmc_info",
- buf, sizeof(buf));
-
- switch (dc_flag) {
- case CHECK_DC3CO:
- igt_skip_on_f(!strstr(buf, "DC3CO count"),
- "DC3CO counter is not available\n");
- break;
- case CHECK_DC5:
- igt_skip_on_f(!strstr(buf, "DC3 -> DC5 count"),
- "DC5 counter is not available\n");
- break;
- case CHECK_DC6:
- str = get_dc6_counter(buf);
- igt_skip_on_f(!str, "No DC6 counter available\n");
- break;
- default:
- igt_assert_f(0, "Unknown DC counter %d\n", dc_flag);
- }
-}
-
static void setup_dc3co(data_t *data)
{
data->op_psr_mode = PSR_MODE_2;
@@ -423,7 +326,7 @@ static void setup_dc3co(data_t *data)
static void test_dc3co_vpb_simulation(data_t *data)
{
- require_dc_counter(data->debugfs_fd, CHECK_DC3CO);
+ igt_require_dc_counter(data->debugfs_fd, CHECK_DC3CO);
setup_output(data);
setup_dc3co(data);
setup_videoplayback(data);
@@ -435,8 +338,8 @@ static void test_dc5_retention_flops(data_t *data, int dc_flag)
{
uint32_t dc_counter_before_psr;
- require_dc_counter(data->debugfs_fd, dc_flag);
- dc_counter_before_psr = read_dc_counter(data->debugfs_fd, dc_flag);
+ igt_require_dc_counter(data->debugfs_fd, dc_flag);
+ dc_counter_before_psr = igt_read_dc_counter(data->debugfs_fd, dc_flag);
set_output_on_pipe_b(data);
setup_primary(data);
igt_assert(psr_wait_entry(data->debugfs_fd, data->op_psr_mode, NULL));
@@ -448,8 +351,8 @@ static void test_dc_state_psr(data_t *data, int dc_flag)
{
uint32_t dc_counter_before_psr;
- require_dc_counter(data->debugfs_fd, dc_flag);
- dc_counter_before_psr = read_dc_counter(data->debugfs_fd, dc_flag);
+ igt_require_dc_counter(data->debugfs_fd, dc_flag);
+ dc_counter_before_psr = igt_read_dc_counter(data->debugfs_fd, dc_flag);
setup_output(data);
setup_primary(data);
igt_require(!psr_disabled_check(data->debugfs_fd));
@@ -512,9 +415,9 @@ static void test_dc_state_dpms(data_t *data, int dc_flag)
{
uint32_t dc_counter;
- require_dc_counter(data->debugfs_fd, dc_flag);
+ igt_require_dc_counter(data->debugfs_fd, dc_flag);
setup_dc_dpms(data);
- dc_counter = read_dc_counter(data->debugfs_fd, dc_flag);
+ dc_counter = igt_read_dc_counter(data->debugfs_fd, dc_flag);
dpms_off(data);
check_dc_counter(data, dc_flag, dc_counter);
dpms_on(data);
@@ -525,23 +428,14 @@ static void test_dc_state_dpms_negative(data_t *data, int dc_flag)
{
uint32_t dc_counter;
- require_dc_counter(data->debugfs_fd, dc_flag);
+ igt_require_dc_counter(data->debugfs_fd, dc_flag);
setup_dc_dpms(data);
- dc_counter = read_dc_counter(data->debugfs_fd, dc_flag);
+ dc_counter = igt_read_dc_counter(data->debugfs_fd, dc_flag);
dpms_on(data);
check_dc_counter_negative(data, dc_flag, dc_counter);
cleanup_dc_dpms(data);
}
-static bool support_dc6(int debugfs_fd)
-{
- char buf[4096];
-
- igt_debugfs_simple_read(debugfs_fd, "i915_dmc_info",
- buf, sizeof(buf));
- return strstr(buf, "DC5 -> DC6 count");
-}
-
static uint64_t read_runtime_suspended_time(int drm_fd)
{
struct pci_device *i915;
@@ -564,7 +458,7 @@ static bool dc9_wait_entry(data_t *data, int dc_target, int prev_dc, uint64_t pr
*/
return igt_wait((read_runtime_suspended_time(data->drm_fd) > prev_rpm) &&
(!DC9_RESETS_DC_COUNTERS(data->devid) ||
- (read_dc_counter(data->debugfs_fd, dc_target) < prev_dc)), msecs, 1000);
+ (igt_read_dc_counter(data->debugfs_fd, dc_target) < prev_dc)), msecs, 1000);
}
static void check_dc9(data_t *data, int dc_target, int prev_dc, int prev_rpm)
@@ -584,12 +478,12 @@ static void setup_dc9_dpms(data_t *data, int dc_target)
__igt_sysfs_set_boolean(sysfs_fd, "poll", KMS_POLL_DISABLE);
close(sysfs_fd);
if (DC9_RESETS_DC_COUNTERS(data->devid)) {
- prev_dc = read_dc_counter(data->debugfs_fd, dc_target);
+ prev_dc = igt_read_dc_counter(data->debugfs_fd, dc_target);
setup_dc_dpms(data);
dpms_off(data);
- igt_skip_on_f(!(igt_wait(read_dc_counter(data->debugfs_fd, dc_target) >
+ igt_skip_on_f(!(igt_wait(igt_read_dc_counter(data->debugfs_fd, dc_target) >
prev_dc, 3000, 100)), "Unable to enters shallow DC states\n");
- prev_dc = read_dc_counter(data->debugfs_fd, dc_target);
+ prev_dc = igt_read_dc_counter(data->debugfs_fd, dc_target);
dpms_on(data);
cleanup_dc_dpms(data);
}
@@ -603,8 +497,8 @@ static void test_dc9_dpms(data_t *data)
{
int dc_target;
- require_dc_counter(data->debugfs_fd, CHECK_DC5);
- dc_target = support_dc6(data->debugfs_fd) ? CHECK_DC6 : CHECK_DC5;
+ igt_require_dc_counter(data->debugfs_fd, CHECK_DC5);
+ dc_target = igt_support_dc6(data->debugfs_fd) ? CHECK_DC6 : CHECK_DC5;
setup_dc9_dpms(data, dc_target);
}
@@ -623,21 +517,6 @@ static int has_panels_without_dc_support(igt_display_t *display)
return external_panel;
}
-static unsigned int read_pkgc_counter(int debugfs_root_fd)
-{
- char buf[4096];
- char *str;
- int len;
-
- len = igt_sysfs_read(debugfs_root_fd, PACKAGE_CSTATE_PATH, buf, sizeof(buf) - 1);
- igt_skip_on_f(len < 0, "PKGC state file not found\n");
- buf[len] = '\0';
- str = strstr(buf, "Package C10");
- igt_skip_on_f(!str, "PKGC10 is not supported.\n");
-
- return get_dc_counter(str);
-}
-
static void test_deep_pkgc_state(data_t *data)
{
unsigned int pre_val = 0, cur_val = 0;
@@ -701,7 +580,7 @@ static void test_deep_pkgc_state(data_t *data)
igt_display_commit(&data->display);
/* Wait for the vblank to sync the frame time */
igt_wait_for_vblank_count(igt_crtc_for_pipe(&data->display, pipe), 1);
- pre_val = read_pkgc_counter(data->debugfs_root_fd);
+ pre_val = igt_read_pkgc_counter(data->debugfs_root_fd);
/* Add a half-frame delay to ensure the flip occurs when the frame is active. */
usleep(delay * 0.5);
@@ -710,7 +589,7 @@ static void test_deep_pkgc_state(data_t *data)
igt_plane_set_fb(primary, flip ? &data->fb_rgb : &data->fb_rgr);
igt_display_commit(&data->display);
- igt_wait((cur_val = read_pkgc_counter(data->debugfs_root_fd)) > pre_val,
+ igt_wait((cur_val = igt_read_pkgc_counter(data->debugfs_root_fd)) > pre_val,
(delay * 2), (5 * MSEC));
if (cur_val > pre_val) {
pkgc_flag = true;
--
2.43.0
next reply other threads:[~2026-01-27 6:34 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-27 6:34 Jeevan B [this message]
2026-01-27 7:58 ` ✓ Xe.CI.BAT: success for lib/igt_pm: Move DC State Counter Functions to common library (rev2) Patchwork
2026-01-27 8:18 ` ✓ i915.CI.BAT: " Patchwork
2026-01-27 9:34 ` ✗ Xe.CI.Full: failure " Patchwork
2026-01-27 12:47 ` ✗ i915.CI.Full: " Patchwork
2026-01-29 15:58 ` [PATCH i-g-t] lib/igt_pm: Move DC State Counter Functions to common library Bilal, Mohammed
-- strict thread matches above, loose matches on Subject: below --
2026-02-13 7:16 Jeevan B
2026-02-10 3:24 Jeevan B
2026-02-10 20:17 ` Thasleem, Mohammed
2026-02-11 13:53 ` Kamil Konieczny
2026-02-09 5:04 Jeevan B
2026-02-09 16:42 ` Kamil Konieczny
2025-12-08 8:39 Jeevan B
2025-12-08 10:31 ` Thasleem, Mohammed
2026-01-12 8:24 ` Thasleem, Mohammed
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=20260127063432.183096-1-jeevan.b@intel.com \
--to=jeevan.b@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=mohammed.thasleem@intel.com \
/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: link
Be 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.