All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Wajdeczko <michal.wajdeczko@intel.com>
To: "Michał Winiarski" <michal.winiarski@intel.com>,
	"Alex Williamson" <alex.williamson@redhat.com>,
	"Lucas De Marchi" <lucas.demarchi@intel.com>,
	"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
	"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
	"Jason Gunthorpe" <jgg@ziepe.ca>,
	"Yishai Hadas" <yishaih@nvidia.com>,
	"Kevin Tian" <kevin.tian@intel.com>,
	"Shameer Kolothum" <shameerali.kolothum.thodi@huawei.com>,
	intel-xe@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org
Cc: <dri-devel@lists.freedesktop.org>,
	Matthew Brost <matthew.brost@intel.com>,
	Jani Nikula <jani.nikula@linux.intel.com>,
	"Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
	Tvrtko Ursulin <tursulin@ursulin.net>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Lukasz Laguna <lukasz.laguna@intel.com>
Subject: Re: [PATCH 25/26] drm/xe/pf: Export helpers for VFIO
Date: Mon, 13 Oct 2025 16:02:36 +0200	[thread overview]
Message-ID: <7cacd33e-e8f2-486b-a507-9b9259e4473d@intel.com> (raw)
In-Reply-To: <20251011193847.1836454-26-michal.winiarski@intel.com>



On 10/11/2025 9:38 PM, Michał Winiarski wrote:
> Vendor-specific VFIO driver for Xe will implement VF migration.
> Export everything that's needed for migration ops.
> 
> Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
> ---
>  drivers/gpu/drm/xe/Makefile        |   2 +
>  drivers/gpu/drm/xe/xe_sriov_vfio.c | 252 +++++++++++++++++++++++++++++
>  include/drm/intel/xe_sriov_vfio.h  |  28 ++++
>  3 files changed, 282 insertions(+)
>  create mode 100644 drivers/gpu/drm/xe/xe_sriov_vfio.c
>  create mode 100644 include/drm/intel/xe_sriov_vfio.h
> 
> diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
> index e253d65366de4..a5c5afff42aa6 100644
> --- a/drivers/gpu/drm/xe/Makefile
> +++ b/drivers/gpu/drm/xe/Makefile
> @@ -181,6 +181,8 @@ xe-$(CONFIG_PCI_IOV) += \
>  	xe_sriov_pf_service.o \
>  	xe_tile_sriov_pf_debugfs.o
>  
> +xe-$(CONFIG_XE_VFIO_PCI) += xe_sriov_vfio.o
> +
>  # include helpers for tests even when XE is built-in
>  ifdef CONFIG_DRM_XE_KUNIT_TEST
>  xe-y += tests/xe_kunit_helpers.o
> diff --git a/drivers/gpu/drm/xe/xe_sriov_vfio.c b/drivers/gpu/drm/xe/xe_sriov_vfio.c
> new file mode 100644
> index 0000000000000..a510d1bde93f0
> --- /dev/null
> +++ b/drivers/gpu/drm/xe/xe_sriov_vfio.c
> @@ -0,0 +1,252 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2025 Intel Corporation
> + */
> +
> +#include <drm/intel/xe_sriov_vfio.h>
> +
> +#include "xe_pm.h"
> +#include "xe_sriov.h"
> +#include "xe_sriov_pf_control.h"
> +#include "xe_sriov_pf_migration.h"
> +#include "xe_sriov_pf_migration_data.h"
> +
> +/**
> + * xe_sriov_vfio_migration_supported() - Check if migration is supported.
> + * @pdev: PF PCI device
> + *
> + * Return: true if migration is supported, false otherwise.
> + */
> +bool xe_sriov_vfio_migration_supported(struct pci_dev *pdev)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +
> +	if (!IS_SRIOV_PF(xe))
> +		return -ENODEV;
> +
> +	return xe_sriov_pf_migration_supported(xe);
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_migration_supported, "xe-vfio-pci");
> +
> +/**
> + * xe_sriov_vfio_wait_flr_done - Wait for VF FLR completion.
> + * @pdev: PF PCI device
> + * @vfid: VF identifier

or

 * @pdev: the PF struct &pci_dev device
 * @vfid: the VF identifier (can't be 0)

> + *
> + * This function will wait until VF FLR is processed by PF on all tiles (or
> + * until timeout occurs).
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_vfio_wait_flr_done(struct pci_dev *pdev, unsigned int vfid)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +
> +	if (!IS_SRIOV_PF(xe))
> +		return -ENODEV;

you also need to validate:

	vfid != PFID
and
	vfid <= xe_sriov_pf_get_totalvfs()

this applies to all exported functions below
> +
> +	return xe_sriov_pf_control_wait_flr(xe, vfid);
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_wait_flr_done, "xe-vfio-pci");
> +
> +/**
> + * xe_sriov_vfio_stop - Stop VF.
> + * @pdev: PF PCI device
> + * @vfid: VF identifier
> + *
> + * This function will pause VF on all tiles/GTs.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_vfio_stop(struct pci_dev *pdev, unsigned int vfid)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +	int ret;
> +
> +	if (!IS_SRIOV_PF(xe))
> +		return -ENODEV;
> +
> +	xe_pm_runtime_get(xe);

maybe we should use xe_pm_runtime_get_if_active() to avoid awaking PF if there are no VFs?

when VFs are enabled xe_pm_runtime_get_if_active() will always return true


> +	ret = xe_sriov_pf_control_pause_vf(xe, vfid);
> +	xe_pm_runtime_put(xe);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_stop, "xe-vfio-pci");
> +
> +/**
> + * xe_sriov_vfio_run - Run VF.
> + * @pdev: PF PCI device
> + * @vfid: VF identifier
> + *
> + * This function will resume VF on all tiles.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_vfio_run(struct pci_dev *pdev, unsigned int vfid)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +	int ret;
> +
> +	if (!IS_SRIOV_PF(xe))
> +		return -ENODEV;
> +
> +	xe_pm_runtime_get(xe);
> +	ret = xe_sriov_pf_control_resume_vf(xe, vfid);
> +	xe_pm_runtime_put(xe);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_run, "xe-vfio-pci");
> +
> +/**
> + * xe_sriov_vfio_stop_copy_enter - Copy VF migration data from device (while stopped).
> + * @pdev: PF PCI device
> + * @vfid: VF identifier
> + *
> + * This function will save VF migration data on all tiles.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_vfio_stop_copy_enter(struct pci_dev *pdev, unsigned int vfid)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +	int ret;
> +
> +	if (!IS_SRIOV_PF(xe))
> +		return -ENODEV;
> +
> +	xe_pm_runtime_get(xe);
> +	ret = xe_sriov_pf_control_save_vf(xe, vfid);
> +	xe_pm_runtime_put(xe);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_stop_copy_enter, "xe-vfio-pci");
> +
> +/**
> + * xe_sriov_vfio_stop_copy_exit - Wait until VF migration data save is done.
> + * @pdev: PF PCI device
> + * @vfid: VF identifier
> + *
> + * This function will wait until VF migration data is saved on all tiles.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_vfio_stop_copy_exit(struct pci_dev *pdev, unsigned int vfid)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +	int ret;
> +
> +	if (!IS_SRIOV_PF(xe))
> +		return -ENODEV;
> +
> +	xe_pm_runtime_get(xe);
> +	ret = xe_sriov_pf_control_wait_save_vf(xe, vfid);
> +	xe_pm_runtime_put(xe);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_stop_copy_exit, "xe-vfio-pci");
> +
> +/**
> + * xe_sriov_vfio_resume_enter - Copy VF migration data to device (while stopped).
> + * @pdev: PF PCI device
> + * @vfid: VF identifier
> + *
> + * This function will restore VF migration data on all tiles.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_vfio_resume_enter(struct pci_dev *pdev, unsigned int vfid)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +	int ret;
> +
> +	if (!IS_SRIOV_PF(xe))
> +		return -ENODEV;
> +
> +	xe_pm_runtime_get(xe);
> +	ret = xe_sriov_pf_control_restore_vf(xe, vfid);
> +	xe_pm_runtime_put(xe);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_resume_enter, "xe-vfio-pci");
> +
> +/**
> + * xe_sriov_vfio_resume_exit - Wait until VF migration data is copied to the device.
> + * @pdev: PF PCI device
> + * @vfid: VF identifier
> + *
> + * This function will wait until VF migration data is restored on all tiles.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_vfio_resume_exit(struct pci_dev *pdev, unsigned int vfid)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +	int ret;
> +
> +	if (!IS_SRIOV_PF(xe))
> +		return -ENODEV;
> +
> +	xe_pm_runtime_get(xe);
> +	ret = xe_sriov_pf_control_wait_restore_vf(xe, vfid);
> +	xe_pm_runtime_put(xe);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_resume_exit, "xe-vfio-pci");
> +
> +/**
> + * xe_sriov_vfio_error - Move VF to error state.
> + * @pdev: PF PCI device
> + * @vfid: VF identifier
> + *
> + * This function will stop VF on all tiles.
> + * Reset is needed to move it out of error state.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_sriov_vfio_error(struct pci_dev *pdev, unsigned int vfid)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +	int ret;
> +
> +	if (!IS_SRIOV_PF(xe))
> +		return -ENODEV;
> +
> +	xe_pm_runtime_get(xe);
> +	ret = xe_sriov_pf_control_stop_vf(xe, vfid);
> +	xe_pm_runtime_put(xe);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_error, "xe-vfio-pci");
> +

add kernel-doc

> +ssize_t xe_sriov_vfio_data_read(struct pci_dev *pdev, unsigned int vfid,
> +				char __user *buf, size_t len)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);

missing param validation

	is PF
	is valid VFID

no RPM ?

> +
> +	return xe_sriov_pf_migration_data_read(xe, vfid, buf, len);
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_data_read, "xe-vfio-pci");
> +
> +ssize_t xe_sriov_vfio_data_write(struct pci_dev *pdev, unsigned int vfid,
> +				 const char __user *buf, size_t len)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +
> +	return xe_sriov_pf_migration_data_write(xe, vfid, buf, len);
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_data_write, "xe-vfio-pci");
> +
> +ssize_t xe_sriov_vfio_stop_copy_size(struct pci_dev *pdev, unsigned int vfid)
> +{
> +	struct xe_device *xe = pci_get_drvdata(pdev);
> +
> +	return xe_sriov_pf_migration_size(xe, vfid);
> +}
> +EXPORT_SYMBOL_FOR_MODULES(xe_sriov_vfio_stop_copy_size, "xe-vfio-pci");
> diff --git a/include/drm/intel/xe_sriov_vfio.h b/include/drm/intel/xe_sriov_vfio.h
> new file mode 100644
> index 0000000000000..24e272f84c0e6
> --- /dev/null
> +++ b/include/drm/intel/xe_sriov_vfio.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2025 Intel Corporation
> + */
> +
> +#ifndef _XE_SRIOV_VFIO_H_
> +#define _XE_SRIOV_VFIO_H_
> +
> +#include <linux/types.h>
> +
> +struct pci_dev;
> +
> +bool xe_sriov_vfio_migration_supported(struct pci_dev *pdev);
> +int xe_sriov_vfio_wait_flr_done(struct pci_dev *pdev, unsigned int vfid);
> +int xe_sriov_vfio_stop(struct pci_dev *pdev, unsigned int vfid);
> +int xe_sriov_vfio_run(struct pci_dev *pdev, unsigned int vfid);
> +int xe_sriov_vfio_stop_copy_enter(struct pci_dev *pdev, unsigned int vfid);
> +int xe_sriov_vfio_stop_copy_exit(struct pci_dev *pdev, unsigned int vfid);
> +int xe_sriov_vfio_resume_enter(struct pci_dev *pdev, unsigned int vfid);
> +int xe_sriov_vfio_resume_exit(struct pci_dev *pdev, unsigned int vfid);
> +int xe_sriov_vfio_error(struct pci_dev *pdev, unsigned int vfid);
> +ssize_t xe_sriov_vfio_data_read(struct pci_dev *pdev, unsigned int vfid,
> +				char __user *buf, size_t len);
> +ssize_t xe_sriov_vfio_data_write(struct pci_dev *pdev, unsigned int vfid,
> +				 const char __user *buf, size_t len);
> +ssize_t xe_sriov_vfio_stop_copy_size(struct pci_dev *pdev, unsigned int vfid);
> +
> +#endif /* _XE_SRIOV_VFIO_H_ */

this is a very simple header, no need to repeat include guard name here


  parent reply	other threads:[~2025-10-13 14:02 UTC|newest]

Thread overview: 84+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-11 19:38 [PATCH 00/26] vfio/xe: Add driver variant for Xe VF migration Michał Winiarski
2025-10-11 19:38 ` [PATCH 01/26] drm/xe/pf: Remove GuC version check for migration support Michał Winiarski
2025-10-12 18:31   ` Michal Wajdeczko
2025-10-20 14:46     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 02/26] drm/xe: Move migration support to device-level struct Michał Winiarski
2025-10-12 18:58   ` Michal Wajdeczko
2025-10-20 14:48     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 03/26] drm/xe/pf: Add save/restore control state stubs and connect to debugfs Michał Winiarski
2025-10-12 20:09   ` Michal Wajdeczko
2025-10-11 19:38 ` [PATCH 04/26] drm/xe/pf: Extract migration mutex out of its struct Michał Winiarski
2025-10-12 19:08   ` Matthew Brost
2025-10-20 14:50     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 05/26] drm/xe/pf: Add data structures and handlers for migration rings Michał Winiarski
2025-10-12 21:06   ` Michal Wajdeczko
2025-10-20 14:56     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 06/26] drm/xe/pf: Add helpers for migration data allocation / free Michał Winiarski
2025-10-12 19:12   ` Matthew Brost
2025-10-21  0:26     ` Michał Winiarski
2025-10-13 10:15   ` Michal Wajdeczko
2025-10-21  0:01     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 07/26] drm/xe/pf: Add support for encap/decap of bitstream to/from packet Michał Winiarski
2025-10-11 22:28   ` kernel test robot
2025-10-13 10:46   ` Michal Wajdeczko
2025-10-21  0:25     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 08/26] drm/xe/pf: Add minimalistic migration descriptor Michał Winiarski
2025-10-11 22:52   ` kernel test robot
2025-10-13 10:56   ` Michal Wajdeczko
2025-10-21  0:31     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 09/26] drm/xe/pf: Expose VF migration data size over debugfs Michał Winiarski
2025-10-12 19:15   ` Matthew Brost
2025-10-21  0:37     ` Michał Winiarski
2025-10-13 11:04   ` Michal Wajdeczko
2025-10-21  0:42     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 10/26] drm/xe: Add sa/guc_buf_cache sync interface Michał Winiarski
2025-10-12 18:06   ` Matthew Brost
2025-10-21  0:45     ` Michał Winiarski
2025-10-13 11:20   ` Michal Wajdeczko
2025-10-21  0:44     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 11/26] drm/xe: Allow the caller to pass guc_buf_cache size Michał Winiarski
2025-10-11 23:35   ` kernel test robot
2025-10-13 11:08   ` Michal Wajdeczko
2025-10-21  0:47     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 12/26] drm/xe/pf: Increase PF GuC Buffer Cache size and use it for VF migration Michał Winiarski
2025-10-13 11:27   ` Michal Wajdeczko
2025-10-21  0:50     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 13/26] drm/xe/pf: Remove GuC migration data save/restore from GT debugfs Michał Winiarski
2025-10-13 11:36   ` Michal Wajdeczko
2025-10-11 19:38 ` [PATCH 14/26] drm/xe/pf: Don't save GuC VF migration data on pause Michał Winiarski
2025-10-13 11:42   ` Michal Wajdeczko
2025-10-11 19:38 ` [PATCH 15/26] drm/xe/pf: Switch VF migration GuC save/restore to struct migration data Michał Winiarski
2025-10-11 19:38 ` [PATCH 16/26] drm/xe/pf: Handle GuC migration data as part of PF control Michał Winiarski
2025-10-13 11:56   ` Michal Wajdeczko
2025-10-21  0:52     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 17/26] drm/xe/pf: Add helpers for VF GGTT migration data handling Michał Winiarski
2025-10-13 12:17   ` Michal Wajdeczko
2025-10-21  1:00     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 18/26] drm/xe/pf: Handle GGTT migration data as part of PF control Michał Winiarski
2025-10-13 12:36   ` Michal Wajdeczko
2025-10-21  1:16     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 19/26] drm/xe/pf: Add helpers for VF MMIO migration data handling Michał Winiarski
2025-10-13 13:28   ` Michal Wajdeczko
2025-10-11 19:38 ` [PATCH 20/26] drm/xe/pf: Handle MMIO migration data as part of PF control Michał Winiarski
2025-10-11 19:38 ` [PATCH 21/26] drm/xe/pf: Add helper to retrieve VF's LMEM object Michał Winiarski
2025-10-11 19:38 ` [PATCH 22/26] drm/xe/migrate: Add function for raw copy of VRAM and CCS Michał Winiarski
2025-10-12 18:54   ` Matthew Brost
2025-10-11 19:38 ` [PATCH 23/26] drm/xe/pf: Handle VRAM migration data as part of PF control Michał Winiarski
2025-10-11 19:38 ` [PATCH 24/26] drm/xe/pf: Add wait helper for VF FLR Michał Winiarski
2025-10-13 13:49   ` Michal Wajdeczko
2025-10-11 19:38 ` [PATCH 25/26] drm/xe/pf: Export helpers for VFIO Michał Winiarski
2025-10-12 18:32   ` Matthew Brost
2025-10-21  1:38     ` Michał Winiarski
2025-10-13 14:02   ` Michal Wajdeczko [this message]
2025-10-21  1:49     ` Michał Winiarski
2025-10-11 19:38 ` [PATCH 26/26] vfio/xe: Add vendor-specific vfio_pci driver for Intel graphics Michał Winiarski
2025-10-13 19:00   ` Rodrigo Vivi
2025-10-21 23:03   ` Jason Gunthorpe
2025-10-21 23:14     ` Matthew Brost
2025-10-21 23:38       ` Jason Gunthorpe
2025-10-22  1:15         ` Matthew Brost
2025-10-22 13:02           ` Jason Gunthorpe
2025-10-22  9:05     ` Michał Winiarski
2025-10-27  7:02       ` Tian, Kevin
2025-10-11 19:48 ` ✗ CI.checkpatch: warning for vfio/xe: Add driver variant for Xe VF migration Patchwork
2025-10-11 19:49 ` ✗ CI.KUnit: failure " 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=7cacd33e-e8f2-486b-a507-9b9259e4473d@intel.com \
    --to=michal.wajdeczko@intel.com \
    --cc=airlied@gmail.com \
    --cc=alex.williamson@redhat.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=jgg@ziepe.ca \
    --cc=joonas.lahtinen@linux.intel.com \
    --cc=kevin.tian@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lucas.demarchi@intel.com \
    --cc=lukasz.laguna@intel.com \
    --cc=matthew.brost@intel.com \
    --cc=michal.winiarski@intel.com \
    --cc=rodrigo.vivi@intel.com \
    --cc=shameerali.kolothum.thodi@huawei.com \
    --cc=simona@ffwll.ch \
    --cc=thomas.hellstrom@linux.intel.com \
    --cc=tursulin@ursulin.net \
    --cc=yishaih@nvidia.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.