All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Williams <dan.j.williams@intel.com>
To: Jonathan Cameron <Jonathan.Cameron@huawei.com>,
	Dan Williams <dan.j.williams@intel.com>
Cc: <linux-cxl@vger.kernel.org>, Ben Widawsky <bwidawsk@kernel.org>,
	<hch@infradead.org>, <alison.schofield@intel.com>,
	<nvdimm@lists.linux.dev>, <linux-pci@vger.kernel.org>,
	<patches@lists.linux.dev>
Subject: Re: [PATCH 10/46] cxl/core: Define a 'struct cxl_root_decoder' for tracking CXL window resources
Date: Sat, 9 Jul 2022 19:20:56 -0700	[thread overview]
Message-ID: <62ca37888d9a4_2da5bd2942@dwillia2-xfh.notmuch> (raw)
In-Reply-To: <20220628174955.00005a53@Huawei.com>

Jonathan Cameron wrote:
> On Thu, 23 Jun 2022 19:46:13 -0700
> Dan Williams <dan.j.williams@intel.com> wrote:
> 
> > Previously the target routing specifics of switch decoders were factored
> > out of 'struct cxl_decoder' into 'struct cxl_switch_decoder'.
> > 
> > This patch, 2 of 3, adds a 'struct cxl_root_decoder' as a superset of a
> > switch decoder that also track the associated CXL window platform
> > resource.
> > 
> > Note that the reason the resource for a given root decoder needs to be
> > looked up after the fact (i.e. after cxl_parse_cfmws() and
> > add_cxl_resource()) is because add_cxl_resource() may have merged CXL
> > windows in order to keep them at the top of the resource tree / decode
> > hierarchy.
> 
> One trivial comment below that follows from earlier patch.
> 
> Otherwise, I'll look again at this when I understand what the constraints
> of CXL windows are that you are dealing with.  I don't get why they might not
> be at the top of the resource tree without the merging!
> 
> > 
> > Co-developed-by: Ben Widawsky <bwidawsk@kernel.org>
> > Signed-off-by: Ben Widawsky <bwidawsk@kernel.org>
> > Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> > ---
> >  drivers/cxl/acpi.c      |   40 ++++++++++++++++++++++++++++++++++++----
> >  drivers/cxl/core/port.c |   43 +++++++++++++++++++++++++++++++++++++------
> >  drivers/cxl/cxl.h       |   15 +++++++++++++--
> >  3 files changed, 86 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
> > index 003fa4fde357..5972f380cdf2 100644
> > --- a/drivers/cxl/acpi.c
> > +++ b/drivers/cxl/acpi.c
> > @@ -82,7 +82,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
> >  	int target_map[CXL_DECODER_MAX_INTERLEAVE];
> >  	struct cxl_cfmws_context *ctx = arg;
> >  	struct cxl_port *root_port = ctx->root_port;
> > -	struct cxl_switch_decoder *cxlsd;
> > +	struct cxl_root_decoder *cxlrd;
> >  	struct device *dev = ctx->dev;
> >  	struct acpi_cedt_cfmws *cfmws;
> >  	struct resource *cxl_res;
> > @@ -128,11 +128,11 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
> >  	if (rc)
> >  		goto err_insert;
> >  
> > -	cxlsd = cxl_root_decoder_alloc(root_port, ways);
> > -	if (IS_ERR(cxld))
> > +	cxlrd = cxl_root_decoder_alloc(root_port, ways);
> > +	if (IS_ERR(cxlrd))
> >  		return 0;
> >  
> > -	cxld = &cxlsd->cxld;
> > +	cxld = &cxlrd->cxlsd.cxld;
> >  	cxld->flags = cfmws_to_decoder_flags(cfmws->restrictions);
> >  	cxld->target_type = CXL_DECODER_EXPANDER;
> >  	cxld->hpa_range = (struct range) {
> > @@ -375,6 +375,32 @@ static int add_cxl_resources(struct resource *cxl)
> >  	return 0;
> >  }
> >  
> > +static int pair_cxl_resource(struct device *dev, void *data)
> > +{
> > +	struct resource *cxl_res = data;
> > +	struct resource *p;
> > +
> > +	if (!is_root_decoder(dev))
> > +		return 0;
> > +
> > +	for (p = cxl_res->child; p; p = p->sibling) {
> > +		struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
> > +		struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
> > +		struct resource res = {
> > +			.start = cxld->hpa_range.start,
> > +			.end = cxld->hpa_range.end,
> > +			.flags = IORESOURCE_MEM,
> > +		};
> > +
> > +		if (resource_contains(p, &res)) {
> > +			cxlrd->res = (struct resource *)p->desc;
> > +			break;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static int cxl_acpi_probe(struct platform_device *pdev)
> >  {
> >  	int rc;
> > @@ -425,6 +451,12 @@ static int cxl_acpi_probe(struct platform_device *pdev)
> >  	if (rc)
> >  		return rc;
> >  
> > +	/*
> > +	 * Populate the root decoders with their related iomem resource,
> > +	 * if present
> > +	 */
> > +	device_for_each_child(&root_port->dev, cxl_res, pair_cxl_resource);
> > +
> >  	/*
> >  	 * Root level scanned with host-bridge as dports, now scan host-bridges
> >  	 * for their role as CXL uports to their CXL-capable PCIe Root Ports.
> > diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> > index fd1cac13cd2e..abf3455c4eff 100644
> > --- a/drivers/cxl/core/port.c
> > +++ b/drivers/cxl/core/port.c
> > @@ -259,6 +259,23 @@ static void cxl_switch_decoder_release(struct device *dev)
> >  	kfree(cxlsd);
> >  }
> >  
> > +struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev)
> > +{
> > +	if (dev_WARN_ONCE(dev, !is_root_decoder(dev),
> > +			  "not a cxl_root_decoder device\n"))
> > +		return NULL;
> > +	return container_of(dev, struct cxl_root_decoder, cxlsd.cxld.dev);
> > +}
> > +EXPORT_SYMBOL_NS_GPL(to_cxl_root_decoder, CXL);
> > +
> > +static void cxl_root_decoder_release(struct device *dev)
> > +{
> > +	struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
> > +
> > +	__cxl_decoder_release(&cxlrd->cxlsd.cxld);
> > +	kfree(cxlrd);
> > +}
> > +
> >  static const struct device_type cxl_decoder_endpoint_type = {
> >  	.name = "cxl_decoder_endpoint",
> >  	.release = cxl_decoder_release,
> > @@ -273,7 +290,7 @@ static const struct device_type cxl_decoder_switch_type = {
> >  
> >  static const struct device_type cxl_decoder_root_type = {
> >  	.name = "cxl_decoder_root",
> > -	.release = cxl_switch_decoder_release,
> > +	.release = cxl_root_decoder_release,
> >  	.groups = cxl_decoder_root_attribute_groups,
> >  };
> >  
> > @@ -1218,9 +1235,23 @@ static struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port,
> >  
> >  	if (nr_targets) {
> >  		struct cxl_switch_decoder *cxlsd;
> > +		struct cxl_root_decoder *cxlrd;
> > +
> > +		if (is_cxl_root(port)) {
> > +			alloc = kzalloc(struct_size(cxlrd, cxlsd.target,
> > +						    nr_targets),
> > +					GFP_KERNEL);
> > +			cxlrd = alloc;
> > +			if (cxlrd)
> > +				cxlsd = &cxlrd->cxlsd;
> > +			else
> > +				cxlsd = NULL;
> > +		} else {
> > +			alloc = kzalloc(struct_size(cxlsd, target, nr_targets),
> > +					GFP_KERNEL);
> > +			cxlsd = alloc;
> 
> As earlier, I'd prefer you just handled errors when they happened rather than
> dancing onwards...

Yes, this gets cleaned up with moving the allocation to
cxl_root_decoder_alloc() directly.

> 
> > +		}
> >  
> > -		alloc = kzalloc(struct_size(cxlsd, target, nr_targets), GFP_KERNEL);
> > -		cxlsd = alloc;
> >  		if (cxlsd) {
> >  			cxlsd->nr_targets = nr_targets;
> >  			seqlock_init(&cxlsd->target_lock);
> > @@ -1279,8 +1310,8 @@ static struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port,
> >   * firmware description of CXL resources into a CXL standard decode
> >   * topology.
> >   */
> > -struct cxl_switch_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
> > -						  unsigned int nr_targets)
> > +struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
> > +						unsigned int nr_targets)
> >  {
> >  	struct cxl_decoder *cxld;
> >  
> > @@ -1290,7 +1321,7 @@ struct cxl_switch_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
> >  	cxld = cxl_decoder_alloc(port, nr_targets);
> >  	if (IS_ERR(cxld))
> >  		return ERR_CAST(cxld);
> > -	return to_cxl_switch_decoder(&cxld->dev);
> > +	return to_cxl_root_decoder(&cxld->dev);
> >  }
> >  EXPORT_SYMBOL_NS_GPL(cxl_root_decoder_alloc, CXL);
> >  
> > diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> > index 7525b55b11bb..6dd1e4c57a67 100644
> > --- a/drivers/cxl/cxl.h
> > +++ b/drivers/cxl/cxl.h
> > @@ -253,6 +253,16 @@ struct cxl_switch_decoder {
> >  	struct cxl_dport *target[];
> >  };
> >  
> > +/**
> > + * struct cxl_root_decoder - Static platform CXL address decoder
> > + * @res: host / parent resource for region allocations
> > + * @cxlsd: base cxl switch decoder
> > + */
> > +struct cxl_root_decoder {
> > +	struct resource *res;
> > +	struct cxl_switch_decoder cxlsd;
> 
> Could be nice to those container of macros and just put the cxlsd first.

Not possible. @cxlsd needs to be the last attribute because it has a
variably sized flex-array at its end.

  reply	other threads:[~2022-07-10  2:21 UTC|newest]

Thread overview: 157+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-24  2:45 [PATCH 00/46] CXL PMEM Region Provisioning Dan Williams
2022-06-24  2:45 ` [PATCH 01/46] tools/testing/cxl: Fix cxl_hdm_decode_init() calling convention Dan Williams
2022-06-28 10:37   ` Jonathan Cameron
     [not found]   ` <CGME20220629174147uscas1p211384ae262e099484440ef285be26c75@uscas1p2.samsung.com>
2022-06-29 17:41     ` Adam Manzanares
2022-07-09 20:06       ` Dan Williams
2022-07-12 22:11         ` Adam Manzanares
2022-06-24  2:45 ` [PATCH 02/46] cxl/port: Keep port->uport valid for the entire life of a port Dan Williams
2022-06-24  3:37   ` Alison Schofield
2022-06-28 11:47   ` Jonathan Cameron
2022-06-28 14:27     ` Dan Williams
     [not found]   ` <CGME20220629174622uscas1p2236a084ce25771a3ab57c6f006632f35@uscas1p2.samsung.com>
2022-06-29 17:46     ` Adam Manzanares
2022-06-24  2:45 ` [PATCH 03/46] cxl/hdm: Use local hdm variable Dan Williams
2022-06-24  3:38   ` Alison Schofield
2022-06-28 15:16   ` Jonathan Cameron
     [not found]   ` <CGME20220629200312uscas1p292303b9325dcbfe59293f002dc9e6b03@uscas1p2.samsung.com>
2022-06-29 20:03     ` Adam Manzanares
2022-06-24  2:45 ` [PATCH 04/46] cxl/core: Rename ->decoder_range ->hpa_range Dan Williams
2022-06-24  3:39   ` Alison Schofield
2022-06-28 15:17   ` Jonathan Cameron
     [not found]   ` <CGME20220629200652uscas1p2c1da644ea63a5de69e14e046379779b1@uscas1p2.samsung.com>
2022-06-29 20:06     ` Adam Manzanares
2022-06-24  2:45 ` [PATCH 05/46] cxl/core: Drop ->platform_res attribute for root decoders Dan Williams
2022-06-28 15:24   ` Jonathan Cameron
2022-07-09 23:33     ` Dan Williams
     [not found]   ` <CGME20220629202117uscas1p2892fb68ae60c4754e2f7d26882a92ae5@uscas1p2.samsung.com>
2022-06-29 20:21     ` Adam Manzanares
2022-07-09 23:38       ` Dan Williams
2022-06-24  2:45 ` [PATCH 06/46] cxl/core: Drop is_cxl_decoder() Dan Williams
2022-06-24  3:48   ` Alison Schofield
2022-06-28 15:25   ` Jonathan Cameron
     [not found]   ` <CGME20220629203448uscas1p264a7f79a1ed7f9257eefcb3064c7d943@uscas1p2.samsung.com>
2022-06-29 20:34     ` Adam Manzanares
2022-06-24  2:45 ` [PATCH 07/46] cxl: Introduce cxl_to_{ways,granularity} Dan Williams
2022-06-28 15:36   ` Jonathan Cameron
2022-07-09 23:52     ` Dan Williams
2022-06-24  2:45 ` [PATCH 08/46] cxl/core: Define a 'struct cxl_switch_decoder' Dan Williams
2022-06-28 16:12   ` Jonathan Cameron
2022-06-30 10:56     ` Jonathan Cameron
2022-07-10  0:49       ` Dan Williams
2022-07-10  0:33     ` Dan Williams
2022-06-24  2:46 ` [PATCH 09/46] cxl/acpi: Track CXL resources in iomem_resource Dan Williams
2022-06-28 16:43   ` Jonathan Cameron
2022-07-10  2:12     ` Dan Williams
2022-07-19 14:24       ` Jonathan Cameron
2022-06-24  2:46 ` [PATCH 10/46] cxl/core: Define a 'struct cxl_root_decoder' for tracking CXL window resources Dan Williams
2022-06-28 16:49   ` Jonathan Cameron
2022-07-10  2:20     ` Dan Williams [this message]
2022-06-28 16:53   ` Jonathan Cameron
2022-06-24  2:46 ` [PATCH 11/46] cxl/core: Define a 'struct cxl_endpoint_decoder' for tracking DPA resources Dan Williams
2022-06-28 16:55   ` Jonathan Cameron
2022-07-10  2:40     ` Dan Williams
2022-06-24  2:46 ` [PATCH 12/46] cxl/mem: Convert partition-info to resources Dan Williams
2022-06-28 17:02   ` Jonathan Cameron
2022-06-24  2:46 ` [PATCH 13/46] cxl/hdm: Require all decoders to be enumerated Dan Williams
2022-06-28 17:04   ` Jonathan Cameron
2022-06-24  2:46 ` [PATCH 14/46] cxl/hdm: Enumerate allocated DPA Dan Williams
2022-06-29 14:43   ` Jonathan Cameron
2022-07-10  3:03     ` Dan Williams
2022-07-19 14:25       ` Jonathan Cameron
2022-06-24  2:46 ` [PATCH 15/46] cxl/Documentation: List attribute permissions Dan Williams
2022-06-28  3:16   ` Alison Schofield
2022-06-29 14:59   ` Jonathan Cameron
2022-06-24  2:46 ` [PATCH 16/46] cxl/hdm: Add 'mode' attribute to decoder objects Dan Williams
2022-06-29 15:28   ` Jonathan Cameron
2022-07-10  3:45     ` Dan Williams
2022-06-24  2:47 ` [PATCH 17/46] cxl/hdm: Track next decoder to allocate Dan Williams
2022-06-29 15:31   ` Jonathan Cameron
2022-07-10  3:55     ` Dan Williams
2022-07-19 14:27       ` Jonathan Cameron
2022-07-10 16:34     ` Dan Williams
2022-06-24  2:47 ` [PATCH 18/46] cxl/hdm: Add support for allocating DPA to an endpoint decoder Dan Williams
2022-06-29 15:56   ` Jonathan Cameron
2022-07-10 16:53     ` Dan Williams
2022-06-24  2:47 ` [PATCH 19/46] cxl/debug: Move debugfs init to cxl_core_init() Dan Williams
2022-06-29 15:58   ` Jonathan Cameron
2022-06-24  2:47 ` [PATCH 20/46] cxl/mem: Add a debugfs version of 'iomem' for DPA, 'dpamem' Dan Williams
2022-06-29 16:08   ` Jonathan Cameron
2022-07-10 17:09     ` Dan Williams
2022-06-24  2:47 ` [PATCH 21/46] tools/testing/cxl: Move cxl_test resources to the top of memory Dan Williams
2022-06-29 16:11   ` Jonathan Cameron
2022-07-10 17:19     ` Dan Williams
2022-06-24  2:47 ` [PATCH 22/46] tools/testing/cxl: Expand CFMWS windows Dan Williams
2022-06-29 16:14   ` Jonathan Cameron
2022-06-24  2:47 ` [PATCH 23/46] tools/testing/cxl: Add partition support Dan Williams
2022-06-29 16:20   ` Jonathan Cameron
2022-06-24  2:48 ` [PATCH 24/46] tools/testing/cxl: Fix decoder default state Dan Williams
2022-06-29 16:22   ` Jonathan Cameron
2022-07-10 17:33     ` Dan Williams
2022-06-24  2:48 ` [PATCH 25/46] cxl/port: Record dport in endpoint references Dan Williams
2022-06-29 16:49   ` Jonathan Cameron
2022-07-10 18:40     ` Dan Williams
2022-06-24  4:19 ` [PATCH 26/46] cxl/port: Record parent dport when adding ports Dan Williams
2022-06-29 17:02   ` Jonathan Cameron
2022-06-24  4:19 ` [PATCH 27/46] cxl/port: Move 'cxl_ep' references to an xarray per port Dan Williams
2022-06-29 17:19   ` Jonathan Cameron
2022-06-24  4:19 ` [PATCH 28/46] cxl/port: Move dport tracking to an xarray Dan Williams
2022-06-30  9:18   ` Jonathan Cameron
2022-07-10 19:06     ` Dan Williams
2022-06-24  4:19 ` [PATCH 29/46] cxl/port: Cache CXL host bridge data Dan Williams
2022-06-30  9:21   ` Jonathan Cameron
2022-07-10 19:09     ` Dan Williams
2022-06-24  4:19 ` [PATCH 30/46] cxl/hdm: Add sysfs attributes for interleave ways + granularity Dan Williams
2022-06-30  9:26   ` Jonathan Cameron
2022-07-10 20:40     ` Dan Williams
2022-07-19 14:32       ` Jonathan Cameron
2022-06-24  4:19 ` [PATCH 31/46] cxl/hdm: Initialize decoder type for memory expander devices Dan Williams
2022-06-30  9:33   ` Jonathan Cameron
2022-06-24  4:19 ` [PATCH 32/46] cxl/mem: Enumerate port targets before adding endpoints Dan Williams
2022-06-30  9:48   ` Jonathan Cameron
2022-07-10 21:01     ` Dan Williams
2022-06-24  4:19 ` [PATCH 33/46] resource: Introduce alloc_free_mem_region() Dan Williams
2022-06-30 10:35   ` Jonathan Cameron
2022-07-10 21:58     ` Dan Williams
2022-06-24  4:19 ` [PATCH 34/46] cxl/region: Add region creation support Dan Williams
2022-06-30 13:17   ` Jonathan Cameron
2022-07-11  0:08     ` Dan Williams
2022-07-19 14:42       ` Jonathan Cameron
2022-06-24  4:19 ` [PATCH 35/46] cxl/region: Add a 'uuid' attribute Dan Williams
2022-06-28 10:29   ` Jonathan Cameron
2022-06-28 14:24     ` Dan Williams
2022-06-24  4:19 ` [PATCH 36/46] cxl/region: Add interleave ways attribute Dan Williams
2022-06-30 13:44   ` Jonathan Cameron
2022-07-11  0:32     ` Dan Williams
2022-07-19 14:47       ` Jonathan Cameron
2022-07-19 22:15         ` Dan Williams
2022-07-20  9:59           ` Jonathan Cameron
2022-06-30 13:45   ` Jonathan Cameron
2022-06-24  4:19 ` [PATCH 37/46] cxl/region: Allocate host physical address (HPA) capacity to new regions Dan Williams
2022-06-30 13:56   ` Jonathan Cameron
2022-07-11  0:47     ` Dan Williams
2022-06-24  4:19 ` [PATCH 38/46] cxl/region: Enable the assignment of endpoint decoders to regions Dan Williams
2022-06-30 14:31   ` Jonathan Cameron
2022-07-11  1:12     ` Dan Williams
2022-06-24  4:19 ` [PATCH 39/46] cxl/acpi: Add a host-bridge index lookup mechanism Dan Williams
2022-06-30 15:48   ` Jonathan Cameron
2022-06-24  4:19 ` [PATCH 40/46] cxl/region: Attach endpoint decoders Dan Williams
2022-06-24 18:25   ` Jonathan Cameron
2022-06-24 18:49     ` Dan Williams
2022-06-24 20:51     ` Dan Williams
2022-06-24 23:21       ` Dan Williams
2022-06-30 16:34   ` Jonathan Cameron
2022-07-11  2:02     ` Dan Williams
2022-06-24  4:19 ` [PATCH 41/46] cxl/region: Program target lists Dan Williams
2022-06-24  4:19 ` [PATCH 42/46] cxl/hdm: Commit decoder state to hardware Dan Williams
2022-06-30 17:05   ` Jonathan Cameron
2022-07-11  3:02     ` Dan Williams
2022-06-24  4:19 ` [PATCH 43/46] cxl/region: Add region driver boiler plate Dan Williams
2022-06-30 17:09   ` Jonathan Cameron
2022-06-24  4:19 ` [PATCH 44/46] cxl/pmem: Delete unused nvdimm attribute Dan Williams
2022-06-30 17:10   ` Jonathan Cameron
2022-06-24  4:19 ` [PATCH 45/46] cxl/pmem: Fix offline_nvdimm_bus() to offline by bridge Dan Williams
2022-06-30 17:14   ` Jonathan Cameron
2022-07-11 19:49     ` Dan Williams
2022-06-24  4:19 ` [PATCH 46/46] cxl/region: Introduce cxl_pmem_region objects Dan Williams
2022-06-30 17:34   ` Jonathan Cameron
2022-07-11 20:05     ` Dan Williams
2022-06-24 15:13 ` [PATCH 00/46] CXL PMEM Region Provisioning Jonathan Cameron
2022-06-24 15:32   ` Dan Williams
2022-06-28  3:12 ` Alison Schofield
2022-06-28  3:34   ` Dan Williams
2022-07-02  2:26 ` Alison Schofield

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=62ca37888d9a4_2da5bd2942@dwillia2-xfh.notmuch \
    --to=dan.j.williams@intel.com \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=alison.schofield@intel.com \
    --cc=bwidawsk@kernel.org \
    --cc=hch@infradead.org \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=nvdimm@lists.linux.dev \
    --cc=patches@lists.linux.dev \
    /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.