All of lore.kernel.org
 help / color / mirror / Atom feed
From: Neil Armstrong <neil.armstrong@linaro.org>
To: Miquel Raynal <miquel.raynal@bootlin.com>,
	Arseniy Krasnov <avkrasnov@sberdevices.ru>
Cc: Liang Yang <liang.yang@amlogic.com>,
	Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Kevin Hilman <khilman@baylibre.com>,
	Jerome Brunet <jbrunet@baylibre.com>,
	Martin Blumenstingl <martin.blumenstingl@googlemail.com>,
	Jianxin Pan <jianxin.pan@amlogic.com>,
	linux-mtd@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org,
	kernel@sberdevices.ru, oxffffaa@gmail.com
Subject: Re: [RFC PATCH v1] mtd: rawnand: meson: invalidate cache on polling ECC bit
Date: Mon, 13 Mar 2023 12:23:12 +0100	[thread overview]
Message-ID: <dc46c06f-6b36-3c1c-bf96-2ef37e29dfdb@linaro.org> (raw)
In-Reply-To: <20230313121808.27170d1b@xps-13>

On 13/03/2023 12:18, Miquel Raynal wrote:
> Hi Arseniy,
> 
> avkrasnov@sberdevices.ru wrote on Mon, 13 Mar 2023 10:36:11 +0300:
> 
>> Hello,
>>
>> we reproduced this problem on one of our boards. It triggers very rare
>> when 'usleep_range()' is present, but when sleeping is removed - it fires
>> always. I suppose problem is with caching, as 'info_buf' memory is mapped by
>> 'dma_map_single()'.
> 
> The fix looks really legitimate, indeed I get that the usleep_range()
> might make it work most of the time but not always. Having this bit in
> a DMA buf area is a bit strange. Well, the fix LGTM anyway.

Yep it looks legitimate!

LGTM


Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

> 
>>
>> Thanks, Arseniy
>>
>> On 13.03.2023 10:32, Arseniy Krasnov wrote:
>>> 'info_buf' memory is cached and driver polls ECC bit in it. This bit
>>> is set by the NAND controller. If 'usleep_range()' returns before device
>>> sets this bit, 'info_buf' will be cached and driver won't see update of
>>> this bit and will loop forever.
>>>
>>> Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
>>> Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
>>> ---
>>>   drivers/mtd/nand/raw/meson_nand.c | 8 +++++++-
>>>   1 file changed, 7 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>> index 5ee01231ac4c..2c05c08a0eaf 100644
>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>> @@ -176,6 +176,7 @@ struct meson_nfc {
>>>   
>>>   	dma_addr_t daddr;
>>>   	dma_addr_t iaddr;
>>> +	u32 info_bytes;
>>>   
>>>   	unsigned long assigned_cs;
>>>   };
>>> @@ -503,6 +504,7 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
>>>   					 nfc->daddr, datalen, dir);
>>>   			return ret;
>>>   		}
>>> +		nfc->info_bytes = infolen;
>>>   		cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
>>>   		writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>>   
>>> @@ -520,8 +522,10 @@ static void meson_nfc_dma_buffer_release(struct nand_chip *nand,
>>>   	struct meson_nfc *nfc = nand_get_controller_data(nand);
>>>   
>>>   	dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir);
>>> -	if (infolen)
>>> +	if (infolen) {
>>>   		dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir);
>>> +		nfc->info_bytes = 0;
>>> +	}
>>>   }
>>>   
>>>   static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
>>> @@ -710,6 +714,8 @@ static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc,
>>>   		usleep_range(10, 15);
>>>   		/* info is updated by nfc dma engine*/
>>>   		smp_rmb();
>>> +		dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes,
>>> +					DMA_FROM_DEVICE);
>>>   		ret = *info & ECC_COMPLETE;
>>>   	} while (!ret);
>>>   }
> 
> 
> Thanks,
> Miquèl


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

WARNING: multiple messages have this Message-ID (diff)
From: Neil Armstrong <neil.armstrong@linaro.org>
To: Miquel Raynal <miquel.raynal@bootlin.com>,
	Arseniy Krasnov <avkrasnov@sberdevices.ru>
Cc: Liang Yang <liang.yang@amlogic.com>,
	Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Kevin Hilman <khilman@baylibre.com>,
	Jerome Brunet <jbrunet@baylibre.com>,
	Martin Blumenstingl <martin.blumenstingl@googlemail.com>,
	Jianxin Pan <jianxin.pan@amlogic.com>,
	linux-mtd@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org,
	kernel@sberdevices.ru, oxffffaa@gmail.com
Subject: Re: [RFC PATCH v1] mtd: rawnand: meson: invalidate cache on polling ECC bit
Date: Mon, 13 Mar 2023 12:23:12 +0100	[thread overview]
Message-ID: <dc46c06f-6b36-3c1c-bf96-2ef37e29dfdb@linaro.org> (raw)
In-Reply-To: <20230313121808.27170d1b@xps-13>

On 13/03/2023 12:18, Miquel Raynal wrote:
> Hi Arseniy,
> 
> avkrasnov@sberdevices.ru wrote on Mon, 13 Mar 2023 10:36:11 +0300:
> 
>> Hello,
>>
>> we reproduced this problem on one of our boards. It triggers very rare
>> when 'usleep_range()' is present, but when sleeping is removed - it fires
>> always. I suppose problem is with caching, as 'info_buf' memory is mapped by
>> 'dma_map_single()'.
> 
> The fix looks really legitimate, indeed I get that the usleep_range()
> might make it work most of the time but not always. Having this bit in
> a DMA buf area is a bit strange. Well, the fix LGTM anyway.

Yep it looks legitimate!

LGTM


Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

> 
>>
>> Thanks, Arseniy
>>
>> On 13.03.2023 10:32, Arseniy Krasnov wrote:
>>> 'info_buf' memory is cached and driver polls ECC bit in it. This bit
>>> is set by the NAND controller. If 'usleep_range()' returns before device
>>> sets this bit, 'info_buf' will be cached and driver won't see update of
>>> this bit and will loop forever.
>>>
>>> Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
>>> Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
>>> ---
>>>   drivers/mtd/nand/raw/meson_nand.c | 8 +++++++-
>>>   1 file changed, 7 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>> index 5ee01231ac4c..2c05c08a0eaf 100644
>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>> @@ -176,6 +176,7 @@ struct meson_nfc {
>>>   
>>>   	dma_addr_t daddr;
>>>   	dma_addr_t iaddr;
>>> +	u32 info_bytes;
>>>   
>>>   	unsigned long assigned_cs;
>>>   };
>>> @@ -503,6 +504,7 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
>>>   					 nfc->daddr, datalen, dir);
>>>   			return ret;
>>>   		}
>>> +		nfc->info_bytes = infolen;
>>>   		cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
>>>   		writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>>   
>>> @@ -520,8 +522,10 @@ static void meson_nfc_dma_buffer_release(struct nand_chip *nand,
>>>   	struct meson_nfc *nfc = nand_get_controller_data(nand);
>>>   
>>>   	dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir);
>>> -	if (infolen)
>>> +	if (infolen) {
>>>   		dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir);
>>> +		nfc->info_bytes = 0;
>>> +	}
>>>   }
>>>   
>>>   static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
>>> @@ -710,6 +714,8 @@ static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc,
>>>   		usleep_range(10, 15);
>>>   		/* info is updated by nfc dma engine*/
>>>   		smp_rmb();
>>> +		dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes,
>>> +					DMA_FROM_DEVICE);
>>>   		ret = *info & ECC_COMPLETE;
>>>   	} while (!ret);
>>>   }
> 
> 
> Thanks,
> Miquèl


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

WARNING: multiple messages have this Message-ID (diff)
From: Neil Armstrong <neil.armstrong@linaro.org>
To: Miquel Raynal <miquel.raynal@bootlin.com>,
	Arseniy Krasnov <avkrasnov@sberdevices.ru>
Cc: Liang Yang <liang.yang@amlogic.com>,
	Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Kevin Hilman <khilman@baylibre.com>,
	Jerome Brunet <jbrunet@baylibre.com>,
	Martin Blumenstingl <martin.blumenstingl@googlemail.com>,
	Jianxin Pan <jianxin.pan@amlogic.com>,
	linux-mtd@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org,
	kernel@sberdevices.ru, oxffffaa@gmail.com
Subject: Re: [RFC PATCH v1] mtd: rawnand: meson: invalidate cache on polling ECC bit
Date: Mon, 13 Mar 2023 12:23:12 +0100	[thread overview]
Message-ID: <dc46c06f-6b36-3c1c-bf96-2ef37e29dfdb@linaro.org> (raw)
In-Reply-To: <20230313121808.27170d1b@xps-13>

On 13/03/2023 12:18, Miquel Raynal wrote:
> Hi Arseniy,
> 
> avkrasnov@sberdevices.ru wrote on Mon, 13 Mar 2023 10:36:11 +0300:
> 
>> Hello,
>>
>> we reproduced this problem on one of our boards. It triggers very rare
>> when 'usleep_range()' is present, but when sleeping is removed - it fires
>> always. I suppose problem is with caching, as 'info_buf' memory is mapped by
>> 'dma_map_single()'.
> 
> The fix looks really legitimate, indeed I get that the usleep_range()
> might make it work most of the time but not always. Having this bit in
> a DMA buf area is a bit strange. Well, the fix LGTM anyway.

Yep it looks legitimate!

LGTM


Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

> 
>>
>> Thanks, Arseniy
>>
>> On 13.03.2023 10:32, Arseniy Krasnov wrote:
>>> 'info_buf' memory is cached and driver polls ECC bit in it. This bit
>>> is set by the NAND controller. If 'usleep_range()' returns before device
>>> sets this bit, 'info_buf' will be cached and driver won't see update of
>>> this bit and will loop forever.
>>>
>>> Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
>>> Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
>>> ---
>>>   drivers/mtd/nand/raw/meson_nand.c | 8 +++++++-
>>>   1 file changed, 7 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>> index 5ee01231ac4c..2c05c08a0eaf 100644
>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>> @@ -176,6 +176,7 @@ struct meson_nfc {
>>>   
>>>   	dma_addr_t daddr;
>>>   	dma_addr_t iaddr;
>>> +	u32 info_bytes;
>>>   
>>>   	unsigned long assigned_cs;
>>>   };
>>> @@ -503,6 +504,7 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
>>>   					 nfc->daddr, datalen, dir);
>>>   			return ret;
>>>   		}
>>> +		nfc->info_bytes = infolen;
>>>   		cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
>>>   		writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>>   
>>> @@ -520,8 +522,10 @@ static void meson_nfc_dma_buffer_release(struct nand_chip *nand,
>>>   	struct meson_nfc *nfc = nand_get_controller_data(nand);
>>>   
>>>   	dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir);
>>> -	if (infolen)
>>> +	if (infolen) {
>>>   		dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir);
>>> +		nfc->info_bytes = 0;
>>> +	}
>>>   }
>>>   
>>>   static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
>>> @@ -710,6 +714,8 @@ static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc,
>>>   		usleep_range(10, 15);
>>>   		/* info is updated by nfc dma engine*/
>>>   		smp_rmb();
>>> +		dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes,
>>> +					DMA_FROM_DEVICE);
>>>   		ret = *info & ECC_COMPLETE;
>>>   	} while (!ret);
>>>   }
> 
> 
> Thanks,
> Miquèl


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

WARNING: multiple messages have this Message-ID (diff)
From: Neil Armstrong <neil.armstrong@linaro.org>
To: Miquel Raynal <miquel.raynal@bootlin.com>,
	Arseniy Krasnov <avkrasnov@sberdevices.ru>
Cc: Liang Yang <liang.yang@amlogic.com>,
	Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Kevin Hilman <khilman@baylibre.com>,
	Jerome Brunet <jbrunet@baylibre.com>,
	Martin Blumenstingl <martin.blumenstingl@googlemail.com>,
	Jianxin Pan <jianxin.pan@amlogic.com>,
	linux-mtd@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org,
	kernel@sberdevices.ru, oxffffaa@gmail.com
Subject: Re: [RFC PATCH v1] mtd: rawnand: meson: invalidate cache on polling ECC bit
Date: Mon, 13 Mar 2023 12:23:12 +0100	[thread overview]
Message-ID: <dc46c06f-6b36-3c1c-bf96-2ef37e29dfdb@linaro.org> (raw)
In-Reply-To: <20230313121808.27170d1b@xps-13>

On 13/03/2023 12:18, Miquel Raynal wrote:
> Hi Arseniy,
> 
> avkrasnov@sberdevices.ru wrote on Mon, 13 Mar 2023 10:36:11 +0300:
> 
>> Hello,
>>
>> we reproduced this problem on one of our boards. It triggers very rare
>> when 'usleep_range()' is present, but when sleeping is removed - it fires
>> always. I suppose problem is with caching, as 'info_buf' memory is mapped by
>> 'dma_map_single()'.
> 
> The fix looks really legitimate, indeed I get that the usleep_range()
> might make it work most of the time but not always. Having this bit in
> a DMA buf area is a bit strange. Well, the fix LGTM anyway.

Yep it looks legitimate!

LGTM


Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

> 
>>
>> Thanks, Arseniy
>>
>> On 13.03.2023 10:32, Arseniy Krasnov wrote:
>>> 'info_buf' memory is cached and driver polls ECC bit in it. This bit
>>> is set by the NAND controller. If 'usleep_range()' returns before device
>>> sets this bit, 'info_buf' will be cached and driver won't see update of
>>> this bit and will loop forever.
>>>
>>> Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
>>> Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
>>> ---
>>>   drivers/mtd/nand/raw/meson_nand.c | 8 +++++++-
>>>   1 file changed, 7 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>> index 5ee01231ac4c..2c05c08a0eaf 100644
>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>> @@ -176,6 +176,7 @@ struct meson_nfc {
>>>   
>>>   	dma_addr_t daddr;
>>>   	dma_addr_t iaddr;
>>> +	u32 info_bytes;
>>>   
>>>   	unsigned long assigned_cs;
>>>   };
>>> @@ -503,6 +504,7 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
>>>   					 nfc->daddr, datalen, dir);
>>>   			return ret;
>>>   		}
>>> +		nfc->info_bytes = infolen;
>>>   		cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
>>>   		writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>>   
>>> @@ -520,8 +522,10 @@ static void meson_nfc_dma_buffer_release(struct nand_chip *nand,
>>>   	struct meson_nfc *nfc = nand_get_controller_data(nand);
>>>   
>>>   	dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir);
>>> -	if (infolen)
>>> +	if (infolen) {
>>>   		dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir);
>>> +		nfc->info_bytes = 0;
>>> +	}
>>>   }
>>>   
>>>   static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
>>> @@ -710,6 +714,8 @@ static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc,
>>>   		usleep_range(10, 15);
>>>   		/* info is updated by nfc dma engine*/
>>>   		smp_rmb();
>>> +		dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes,
>>> +					DMA_FROM_DEVICE);
>>>   		ret = *info & ECC_COMPLETE;
>>>   	} while (!ret);
>>>   }
> 
> 
> Thanks,
> Miquèl


  reply	other threads:[~2023-03-13 11:23 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-13  7:32 [RFC PATCH v1] mtd: rawnand: meson: invalidate cache on polling ECC bit Arseniy Krasnov
2023-03-13  7:32 ` Arseniy Krasnov
2023-03-13  7:32 ` Arseniy Krasnov
2023-03-13  7:32 ` Arseniy Krasnov
2023-03-13  7:36 ` Arseniy Krasnov
2023-03-13  7:36   ` Arseniy Krasnov
2023-03-13  7:36   ` Arseniy Krasnov
2023-03-13  7:36   ` Arseniy Krasnov
2023-03-13 11:18   ` Miquel Raynal
2023-03-13 11:18     ` Miquel Raynal
2023-03-13 11:18     ` Miquel Raynal
2023-03-13 11:18     ` Miquel Raynal
2023-03-13 11:23     ` Neil Armstrong [this message]
2023-03-13 11:23       ` Neil Armstrong
2023-03-13 11:23       ` Neil Armstrong
2023-03-13 11:23       ` Neil Armstrong
2023-03-20 10:43       ` Dmitry Rokosov
2023-03-20 10:43         ` Dmitry Rokosov
2023-03-20 10:43         ` Dmitry Rokosov
2023-03-20 10:43         ` Dmitry Rokosov
2023-03-20 10:55         ` Miquel Raynal
2023-03-20 10:55           ` Miquel Raynal
2023-03-20 10:55           ` Miquel Raynal
2023-03-20 10:55           ` Miquel Raynal
2023-03-20 11:30           ` Dmitry Rokosov
2023-03-20 11:30             ` Dmitry Rokosov
2023-03-20 11:30             ` Dmitry Rokosov
2023-03-20 11:30             ` Dmitry Rokosov
2023-03-22 16:07 ` Miquel Raynal
2023-03-22 16:07   ` Miquel Raynal
2023-03-22 16:07   ` Miquel Raynal
2023-03-22 16:07   ` Miquel Raynal

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=dc46c06f-6b36-3c1c-bf96-2ef37e29dfdb@linaro.org \
    --to=neil.armstrong@linaro.org \
    --cc=avkrasnov@sberdevices.ru \
    --cc=jbrunet@baylibre.com \
    --cc=jianxin.pan@amlogic.com \
    --cc=kernel@sberdevices.ru \
    --cc=khilman@baylibre.com \
    --cc=liang.yang@amlogic.com \
    --cc=linux-amlogic@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=martin.blumenstingl@googlemail.com \
    --cc=miquel.raynal@bootlin.com \
    --cc=oxffffaa@gmail.com \
    --cc=richard@nod.at \
    --cc=vigneshr@ti.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.