All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function
@ 2015-06-11  8:27 Wei Wang
  2015-06-18 14:30 ` Jan Beulich
  0 siblings, 1 reply; 8+ messages in thread
From: Wei Wang @ 2015-06-11  8:27 UTC (permalink / raw)
  To: xen-devel, jbeulich; +Cc: andrew.cooper3, Wei Wang

Register the CPU hotplug notifier when the driver is
registered, and move the driver register function to
the cpufreq.c.

Signed-off-by: Wei Wang <wei.w.wang@intel.com>
---
 xen/drivers/cpufreq/cpufreq.c      | 15 ++++++++++++---
 xen/include/acpi/cpufreq/cpufreq.h | 28 ++--------------------------
 2 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c
index ab66884..7d186db 100644
--- a/xen/drivers/cpufreq/cpufreq.c
+++ b/xen/drivers/cpufreq/cpufreq.c
@@ -630,12 +630,21 @@ static struct notifier_block cpu_nfb = {
     .notifier_call = cpu_callback
 };
 
-static int __init cpufreq_presmp_init(void)
+int cpufreq_register_driver(struct cpufreq_driver *driver_data)
 {
     void *cpu = (void *)(long)smp_processor_id();
     cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
+    if (!driver_data || !driver_data->init
+        || !driver_data->verify || !driver_data->exit
+        || (!driver_data->target == !driver_data->setpolicy))
+        return -EINVAL;
+
+    if (cpufreq_driver)
+        return -EBUSY;
+
+    cpufreq_driver = driver_data;
+
     register_cpu_notifier(&cpu_nfb);
+
     return 0;
 }
-presmp_initcall(cpufreq_presmp_init);
-
diff --git a/xen/include/acpi/cpufreq/cpufreq.h b/xen/include/acpi/cpufreq/cpufreq.h
index 60caf59..d10e4c7 100644
--- a/xen/include/acpi/cpufreq/cpufreq.h
+++ b/xen/include/acpi/cpufreq/cpufreq.h
@@ -171,32 +171,8 @@ struct cpufreq_driver {
 
 extern struct cpufreq_driver *cpufreq_driver;
 
-static __inline__ 
-int cpufreq_register_driver(struct cpufreq_driver *driver_data)
-{
-    if (!driver_data         || 
-        !driver_data->init   || 
-        !driver_data->exit   || 
-        !driver_data->verify || 
-        !driver_data->target)
-        return -EINVAL;
-
-    if (cpufreq_driver)
-        return -EBUSY;
-
-    cpufreq_driver = driver_data;
-    return 0;
-}
-
-static __inline__ 
-int cpufreq_unregister_driver(struct cpufreq_driver *driver)
-{
-    if (!cpufreq_driver || (driver != cpufreq_driver))
-        return -EINVAL;
-
-    cpufreq_driver = NULL;
-    return 0;
-}
+extern int cpufreq_register_driver(struct cpufreq_driver *driver_data);
+extern int cpufreq_unregister_driver(struct cpufreq_driver *driver);
 
 static __inline__
 void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function
  2015-06-11  8:27 [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function Wei Wang
@ 2015-06-18 14:30 ` Jan Beulich
  2015-06-23  3:40   ` Wang, Wei W
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Beulich @ 2015-06-18 14:30 UTC (permalink / raw)
  To: Wei Wang; +Cc: andrew.cooper3, xen-devel

>>> On 11.06.15 at 10:27, <wei.w.wang@intel.com> wrote:
> Register the CPU hotplug notifier when the driver is
> registered, and move the driver register function to
> the cpufreq.c.

The first half of the sentence fails to say why. And I suppose if you
explained that (to yourself) you'd figure that the change is wrong (or
at least altering behavior in a way that needs more explanation to
be verifiably correct): The calls to cpufreq_register_driver() sit in
__initcall handlers, yet what you replace is a presmp_initcall. I.e. all
APs being brought up at boot time won't get the callback invoked for
them anymore.

I suppose you tested your series on a system where the new driver
will kick in. You of course also need to test the case where this isn't
the case - everything needs to continue to function there.

> --- a/xen/drivers/cpufreq/cpufreq.c
> +++ b/xen/drivers/cpufreq/cpufreq.c
> @@ -630,12 +630,21 @@ static struct notifier_block cpu_nfb = {
>      .notifier_call = cpu_callback
>  };
>  
> -static int __init cpufreq_presmp_init(void)
> +int cpufreq_register_driver(struct cpufreq_driver *driver_data)
>  {
>      void *cpu = (void *)(long)smp_processor_id();
>      cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
> +    if (!driver_data || !driver_data->init
> +        || !driver_data->verify || !driver_data->exit
> +        || (!driver_data->target == !driver_data->setpolicy))

Do you really want/need to enforce this policy (target set if and only
if setpolicy is not set) here? And if that's to uniformly hold, the two
could be put into a union...

Also - coding style.

> --- a/xen/include/acpi/cpufreq/cpufreq.h
> +++ b/xen/include/acpi/cpufreq/cpufreq.h
> @@ -171,32 +171,8 @@ struct cpufreq_driver {
>  
>  extern struct cpufreq_driver *cpufreq_driver;
>  
> -static __inline__ 
> -int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> -{
> -    if (!driver_data         || 
> -        !driver_data->init   || 
> -        !driver_data->exit   || 
> -        !driver_data->verify || 
> -        !driver_data->target)
> -        return -EINVAL;
> -
> -    if (cpufreq_driver)
> -        return -EBUSY;
> -
> -    cpufreq_driver = driver_data;
> -    return 0;
> -}
> -
> -static __inline__ 
> -int cpufreq_unregister_driver(struct cpufreq_driver *driver)
> -{
> -    if (!cpufreq_driver || (driver != cpufreq_driver))
> -        return -EINVAL;
> -
> -    cpufreq_driver = NULL;
> -    return 0;
> -}
> +extern int cpufreq_register_driver(struct cpufreq_driver *driver_data);
> +extern int cpufreq_unregister_driver(struct cpufreq_driver *driver);

What's this declaration good for when there's no implementation?

Jan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function
  2015-06-18 14:30 ` Jan Beulich
@ 2015-06-23  3:40   ` Wang, Wei W
  2015-06-23  7:31     ` Jan Beulich
  0 siblings, 1 reply; 8+ messages in thread
From: Wang, Wei W @ 2015-06-23  3:40 UTC (permalink / raw)
  To: Jan Beulich; +Cc: andrew.cooper3@citrix.com, xen-devel@lists.xen.org

On 18/06/2015 22:30, Jan Beulich wrote:
> >>> On 11.06.15 at 10:27, <wei.w.wang@intel.com> wrote:
> > Register the CPU hotplug notifier when the driver is registered, and
> > move the driver register function to the cpufreq.c.
> 
> The first half of the sentence fails to say why. And I suppose if you explained
> that (to yourself) you'd figure that the change is wrong (or at least altering
> behavior in a way that needs more explanation to be verifiably correct): The
> calls to cpufreq_register_driver() sit in __initcall handlers, yet what you
> replace is a presmp_initcall. I.e. all APs being brought up at boot time won't
> get the callback invoked for them anymore.
> 
> I suppose you tested your series on a system where the new driver will kick
> in. You of course also need to test the case where this isn't the case -
> everything needs to continue to function there.

The cpu_callback() is removed in the following patch (05/11) because it's redundant.
Functions in cpufreq_register_driver() are also called only once, because other calls to cpufreq_register_driver() will just return due to the unsuccessful condition check at the beginning of the function.

> 
> > --- a/xen/drivers/cpufreq/cpufreq.c
> > +++ b/xen/drivers/cpufreq/cpufreq.c
> > @@ -630,12 +630,21 @@ static struct notifier_block cpu_nfb = {
> >      .notifier_call = cpu_callback
> >  };
> >
> > -static int __init cpufreq_presmp_init(void)
> > +int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> >  {
> >      void *cpu = (void *)(long)smp_processor_id();
> >      cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
> > +    if (!driver_data || !driver_data->init
> > +        || !driver_data->verify || !driver_data->exit
> > +        || (!driver_data->target == !driver_data->setpolicy))
> 
> Do you really want/need to enforce this policy (target set if and only if
> setpolicy is not set) here? And if that's to uniformly hold, the two could be
> put into a union...

driver_data->target() is used by a driver which relies on the old Governor framework.
driver_data->setpolicy() is used by a driver which implements its internal governor.
So, the driver either uses the old Governor framework or has its own private internal governor.
We shouldn't change to use union, because in many places, we distinguish the two by checking if it's using "->target" or "->setpolicy".

Best,
Wei

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function
  2015-06-23  3:40   ` Wang, Wei W
@ 2015-06-23  7:31     ` Jan Beulich
  2015-06-23  8:01       ` Wang, Wei W
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Beulich @ 2015-06-23  7:31 UTC (permalink / raw)
  To: Wei W Wang; +Cc: andrew.cooper3@citrix.com, xen-devel@lists.xen.org

>>> On 23.06.15 at 05:40, <wei.w.wang@intel.com> wrote:
> On 18/06/2015 22:30, Jan Beulich wrote:
>> >>> On 11.06.15 at 10:27, <wei.w.wang@intel.com> wrote:
>> > Register the CPU hotplug notifier when the driver is registered, and
>> > move the driver register function to the cpufreq.c.
>> 
>> The first half of the sentence fails to say why. And I suppose if you 
> explained
>> that (to yourself) you'd figure that the change is wrong (or at least 
> altering
>> behavior in a way that needs more explanation to be verifiably correct): The
>> calls to cpufreq_register_driver() sit in __initcall handlers, yet what you
>> replace is a presmp_initcall. I.e. all APs being brought up at boot time won't
>> get the callback invoked for them anymore.
>> 
>> I suppose you tested your series on a system where the new driver will kick
>> in. You of course also need to test the case where this isn't the case -
>> everything needs to continue to function there.
> 
> The cpu_callback() is removed in the following patch (05/11) because it's 
> redundant.
> Functions in cpufreq_register_driver() are also called only once, because 
> other calls to cpufreq_register_driver() will just return due to the 
> unsuccessful condition check at the beginning of the function.

If this is the case today, then the removal should be a separate
patch early in the series (properly explaining the situation).

>> > --- a/xen/drivers/cpufreq/cpufreq.c
>> > +++ b/xen/drivers/cpufreq/cpufreq.c
>> > @@ -630,12 +630,21 @@ static struct notifier_block cpu_nfb = {
>> >      .notifier_call = cpu_callback
>> >  };
>> >
>> > -static int __init cpufreq_presmp_init(void)
>> > +int cpufreq_register_driver(struct cpufreq_driver *driver_data)
>> >  {
>> >      void *cpu = (void *)(long)smp_processor_id();
>> >      cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
>> > +    if (!driver_data || !driver_data->init
>> > +        || !driver_data->verify || !driver_data->exit
>> > +        || (!driver_data->target == !driver_data->setpolicy))
>> 
>> Do you really want/need to enforce this policy (target set if and only if
>> setpolicy is not set) here? And if that's to uniformly hold, the two could be
>> put into a union...
> 
> driver_data->target() is used by a driver which relies on the old Governor 
> framework.
> driver_data->setpolicy() is used by a driver which implements its internal 
> governor.
> So, the driver either uses the old Governor framework or has its own private 
> internal governor.
> We shouldn't change to use union, because in many places, we distinguish the 
> two by checking if it's using "->target" or "->setpolicy".

The distinction between the two driver modes shouldn't be based on
arbitrary accessors they may or may not implement. There should be
a dedicated flag or alike.

Jan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function
  2015-06-23  7:31     ` Jan Beulich
@ 2015-06-23  8:01       ` Wang, Wei W
  2015-06-23  8:11         ` Jan Beulich
  0 siblings, 1 reply; 8+ messages in thread
From: Wang, Wei W @ 2015-06-23  8:01 UTC (permalink / raw)
  To: Jan Beulich; +Cc: andrew.cooper3@citrix.com, xen-devel@lists.xen.org

On 23/06/2015 15:31, Jan Beulich wrote:
> >>> On 23.06.15 at 05:40, <wei.w.wang@intel.com> wrote:
> > On 18/06/2015 22:30, Jan Beulich wrote:
> >> >>> On 11.06.15 at 10:27, <wei.w.wang@intel.com> wrote:
> >> > -static int __init cpufreq_presmp_init(void)
> >> > +int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> >> >  {
> >> >      void *cpu = (void *)(long)smp_processor_id();
> >> >      cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
> >> > +    if (!driver_data || !driver_data->init
> >> > +        || !driver_data->verify || !driver_data->exit
> >> > +        || (!driver_data->target == !driver_data->setpolicy))
> >>
> >> Do you really want/need to enforce this policy (target set if and
> >> only if setpolicy is not set) here? And if that's to uniformly hold,
> >> the two could be put into a union...
> >
> > driver_data->target() is used by a driver which relies on the old
> > Governor framework.
> > driver_data->setpolicy() is used by a driver which implements its
> > internal governor.
> > So, the driver either uses the old Governor framework or has its own
> > private internal governor.
> > We shouldn't change to use union, because in many places, we
> > distinguish the two by checking if it's using "->target" or "->setpolicy".
> 
> The distinction between the two driver modes shouldn't be based on
> arbitrary accessors they may or may not implement. There should be a
> dedicated flag or alike.

This is not arbitrary - "->target()" is dedicated to the Governor framework, and "->setpolicy" is dedicated to the internal governor implementation. The Linux kernel also takes advantage of this method. I think we don't need to add another new functionally equivalent flag to do so.
Shall we keep using it?

Best,
Wei

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function
  2015-06-23  8:01       ` Wang, Wei W
@ 2015-06-23  8:11         ` Jan Beulich
  2015-06-23  8:24           ` Wang, Wei W
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Beulich @ 2015-06-23  8:11 UTC (permalink / raw)
  To: Wei W Wang; +Cc: andrew.cooper3@citrix.com, xen-devel@lists.xen.org

>>> On 23.06.15 at 10:01, <wei.w.wang@intel.com> wrote:
> On 23/06/2015 15:31, Jan Beulich wrote:
>> >>> On 23.06.15 at 05:40, <wei.w.wang@intel.com> wrote:
>> > On 18/06/2015 22:30, Jan Beulich wrote:
>> >> >>> On 11.06.15 at 10:27, <wei.w.wang@intel.com> wrote:
>> >> > -static int __init cpufreq_presmp_init(void)
>> >> > +int cpufreq_register_driver(struct cpufreq_driver *driver_data)
>> >> >  {
>> >> >      void *cpu = (void *)(long)smp_processor_id();
>> >> >      cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
>> >> > +    if (!driver_data || !driver_data->init
>> >> > +        || !driver_data->verify || !driver_data->exit
>> >> > +        || (!driver_data->target == !driver_data->setpolicy))
>> >>
>> >> Do you really want/need to enforce this policy (target set if and
>> >> only if setpolicy is not set) here? And if that's to uniformly hold,
>> >> the two could be put into a union...
>> >
>> > driver_data->target() is used by a driver which relies on the old
>> > Governor framework.
>> > driver_data->setpolicy() is used by a driver which implements its
>> > internal governor.
>> > So, the driver either uses the old Governor framework or has its own
>> > private internal governor.
>> > We shouldn't change to use union, because in many places, we
>> > distinguish the two by checking if it's using "->target" or "->setpolicy".
>> 
>> The distinction between the two driver modes shouldn't be based on
>> arbitrary accessors they may or may not implement. There should be a
>> dedicated flag or alike.
> 
> This is not arbitrary - "->target()" is dedicated to the Governor framework, 
> and "->setpolicy" is dedicated to the internal governor implementation. The 
> Linux kernel also takes advantage of this method. I think we don't need to 
> add another new functionally equivalent flag to do so.
> Shall we keep using it?

If this distinction is being made clear by comments accompanying
the definitions of the target and setpolicy fields, I'm fine with
keeping it that way. Without making this explicit it would continue
to look arbitrary (and prone to break, should another driver
elect to also implement the setpolicy hook [for whatever purpose]).

Jan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function
  2015-06-23  8:11         ` Jan Beulich
@ 2015-06-23  8:24           ` Wang, Wei W
  2015-06-23  8:37             ` Jan Beulich
  0 siblings, 1 reply; 8+ messages in thread
From: Wang, Wei W @ 2015-06-23  8:24 UTC (permalink / raw)
  To: Jan Beulich; +Cc: andrew.cooper3@citrix.com, xen-devel@lists.xen.org

On 23/06/2015 16:11, Jan Beulich wrote:
> >>> On 23.06.15 at 10:01, <wei.w.wang@intel.com> wrote:
> > On 23/06/2015 15:31, Jan Beulich wrote:
> >> >>> On 23.06.15 at 05:40, <wei.w.wang@intel.com> wrote:
> >> > On 18/06/2015 22:30, Jan Beulich wrote:
> >> >> >>> On 11.06.15 at 10:27, <wei.w.wang@intel.com> wrote:
> >> >> > -static int __init cpufreq_presmp_init(void)
> >> >> > +int cpufreq_register_driver(struct cpufreq_driver *driver_data)
> >> >> >  {
> >> >> >      void *cpu = (void *)(long)smp_processor_id();
> >> >> >      cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
> >> >> > +    if (!driver_data || !driver_data->init
> >> >> > +        || !driver_data->verify || !driver_data->exit
> >> >> > +        || (!driver_data->target == !driver_data->setpolicy))
> >> >>
> >> >> Do you really want/need to enforce this policy (target set if and
> >> >> only if setpolicy is not set) here? And if that's to uniformly
> >> >> hold, the two could be put into a union...
> >> >
> >> > driver_data->target() is used by a driver which relies on the old
> >> > Governor framework.
> >> > driver_data->setpolicy() is used by a driver which implements its
> >> > internal governor.
> >> > So, the driver either uses the old Governor framework or has its
> >> > own private internal governor.
> >> > We shouldn't change to use union, because in many places, we
> >> > distinguish the two by checking if it's using "->target" or "->setpolicy".
> >>
> >> The distinction between the two driver modes shouldn't be based on
> >> arbitrary accessors they may or may not implement. There should be a
> >> dedicated flag or alike.
> >
> > This is not arbitrary - "->target()" is dedicated to the Governor
> > framework, and "->setpolicy" is dedicated to the internal governor
> > implementation. The Linux kernel also takes advantage of this method.
> > I think we don't need to add another new functionally equivalent flag to do
> so.
> > Shall we keep using it?
> 
> If this distinction is being made clear by comments accompanying the
> definitions of the target and setpolicy fields, I'm fine with keeping it that way.
> Without making this explicit it would continue to look arbitrary (and prone to
> break, should another driver elect to also implement the setpolicy hook [for
> whatever purpose]).

OK, I will add some explanation to the related commit message.

Best,
Wei

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function
  2015-06-23  8:24           ` Wang, Wei W
@ 2015-06-23  8:37             ` Jan Beulich
  0 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2015-06-23  8:37 UTC (permalink / raw)
  To: Wei W Wang; +Cc: andrew.cooper3@citrix.com, xen-devel@lists.xen.org

>>> On 23.06.15 at 10:24, <wei.w.wang@intel.com> wrote:
> On 23/06/2015 16:11, Jan Beulich wrote:
>> >>> On 23.06.15 at 10:01, <wei.w.wang@intel.com> wrote:
>> > On 23/06/2015 15:31, Jan Beulich wrote:
>> >> >>> On 23.06.15 at 05:40, <wei.w.wang@intel.com> wrote:
>> >> > On 18/06/2015 22:30, Jan Beulich wrote:
>> >> >> >>> On 11.06.15 at 10:27, <wei.w.wang@intel.com> wrote:
>> >> >> > -static int __init cpufreq_presmp_init(void)
>> >> >> > +int cpufreq_register_driver(struct cpufreq_driver *driver_data)
>> >> >> >  {
>> >> >> >      void *cpu = (void *)(long)smp_processor_id();
>> >> >> >      cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
>> >> >> > +    if (!driver_data || !driver_data->init
>> >> >> > +        || !driver_data->verify || !driver_data->exit
>> >> >> > +        || (!driver_data->target == !driver_data->setpolicy))
>> >> >>
>> >> >> Do you really want/need to enforce this policy (target set if and
>> >> >> only if setpolicy is not set) here? And if that's to uniformly
>> >> >> hold, the two could be put into a union...
>> >> >
>> >> > driver_data->target() is used by a driver which relies on the old
>> >> > Governor framework.
>> >> > driver_data->setpolicy() is used by a driver which implements its
>> >> > internal governor.
>> >> > So, the driver either uses the old Governor framework or has its
>> >> > own private internal governor.
>> >> > We shouldn't change to use union, because in many places, we
>> >> > distinguish the two by checking if it's using "->target" or "->setpolicy".
>> >>
>> >> The distinction between the two driver modes shouldn't be based on
>> >> arbitrary accessors they may or may not implement. There should be a
>> >> dedicated flag or alike.
>> >
>> > This is not arbitrary - "->target()" is dedicated to the Governor
>> > framework, and "->setpolicy" is dedicated to the internal governor
>> > implementation. The Linux kernel also takes advantage of this method.
>> > I think we don't need to add another new functionally equivalent flag to do
>> so.
>> > Shall we keep using it?
>> 
>> If this distinction is being made clear by comments accompanying the
>> definitions of the target and setpolicy fields, I'm fine with keeping it that way.
>> Without making this explicit it would continue to look arbitrary (and prone to
>> break, should another driver elect to also implement the setpolicy hook [for
>> whatever purpose]).
> 
> OK, I will add some explanation to the related commit message.

The commit message will not (normally) be read by people wanting
to make further adjustments to the code. Such an explanation
belongs - as I said - alongside the field declarations.

Jan

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-06-23  8:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-11  8:27 [PATCH v3 04/11] x86/intel_pstate: relocate the driver register function Wei Wang
2015-06-18 14:30 ` Jan Beulich
2015-06-23  3:40   ` Wang, Wei W
2015-06-23  7:31     ` Jan Beulich
2015-06-23  8:01       ` Wang, Wei W
2015-06-23  8:11         ` Jan Beulich
2015-06-23  8:24           ` Wang, Wei W
2015-06-23  8:37             ` Jan Beulich

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.