linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
@ 2022-04-13 22:55 Fabio M. De Francesco
  2022-04-14  0:44 ` Alison Schofield
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Fabio M. De Francesco @ 2022-04-13 22:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus, Greg Kroah-Hartman,
	Hans Verkuil, Tsuchiya Yuto, Martiros Shakhzadyan, Hans de Goede,
	linux-media, linux-staging, linux-kernel, Ira Weiny, outreachy
  Cc: Fabio M. De Francesco

The use of kmap() is being deprecated in favor of kmap_local_page()
where it is feasible. The same is true for kmap_atomic().

In file pci/hmm/hmm.c, function hmm_store() test if we are in atomic
context and, if so, it calls kmap_atomic(), if not, it calls kmap().

First of all, in_atomic() shouldn't be used in drivers. This macro
cannot always detect atomic context; in particular, it cannot know
about held spinlocks in non-preemptible kernels.

Notwithstanding what it is said above, this code doesn't need to care
whether or not it is executing in atomic context. It can simply use
kmap_local_page() / kunmap_local() that can instead do the mapping /
unmapping regardless of the context.

With kmap_local_page(), the mapping is per thread, CPU local and not
globally visible. Therefore, hmm_store()() is a function where the use
of kmap_local_page() in place of both kmap() and kmap_atomic() is
correctly suited.

Convert the calls of kmap() / kunmap() and kmap_atomic() /
kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
unnecessary tests which test if the code is in atomic context.

Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
---
 drivers/staging/media/atomisp/pci/hmm/hmm.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm.c b/drivers/staging/media/atomisp/pci/hmm/hmm.c
index 46ac082cd3f1..54188197c3dc 100644
--- a/drivers/staging/media/atomisp/pci/hmm/hmm.c
+++ b/drivers/staging/media/atomisp/pci/hmm/hmm.c
@@ -482,10 +482,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
 		idx = (virt - bo->start) >> PAGE_SHIFT;
 		offset = (virt - bo->start) - (idx << PAGE_SHIFT);
 
-		if (in_atomic())
-			des = (char *)kmap_atomic(bo->page_obj[idx].page);
-		else
-			des = (char *)kmap(bo->page_obj[idx].page);
+		des = (char *)kmap_local_page(bo->page_obj[idx].page);
 
 		if (!des) {
 			dev_err(atomisp_dev,
@@ -512,14 +509,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
 
 		clflush_cache_range(des, len);
 
-		if (in_atomic())
-			/*
-			 * Note: kunmap_atomic requires return addr from
-			 * kmap_atomic, not the page. See linux/highmem.h
-			 */
-			kunmap_atomic(des - offset);
-		else
-			kunmap(bo->page_obj[idx].page);
+		kunmap_local(des);
 	}
 
 	return 0;
-- 
2.34.1


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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-13 22:55 [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store() Fabio M. De Francesco
@ 2022-04-14  0:44 ` Alison Schofield
  2022-04-14  1:54   ` Ira Weiny
  2022-04-15  0:37 ` Ira Weiny
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Alison Schofield @ 2022-04-14  0:44 UTC (permalink / raw)
  To: Fabio M. De Francesco
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Greg Kroah-Hartman,
	Hans Verkuil, Tsuchiya Yuto, Martiros Shakhzadyan, Hans de Goede,
	linux-media, linux-staging, linux-kernel, Ira Weiny, outreachy

On Thu, Apr 14, 2022 at 12:55:31AM +0200, Fabio M. De Francesco wrote:
> The use of kmap() is being deprecated in favor of kmap_local_page()
> where it is feasible. The same is true for kmap_atomic().
> 
> In file pci/hmm/hmm.c, function hmm_store() test if we are in atomic
> context and, if so, it calls kmap_atomic(), if not, it calls kmap().
> 
> First of all, in_atomic() shouldn't be used in drivers. This macro
> cannot always detect atomic context; in particular, it cannot know
> about held spinlocks in non-preemptible kernels.
> 
> Notwithstanding what it is said above, this code doesn't need to care
> whether or not it is executing in atomic context. It can simply use
> kmap_local_page() / kunmap_local() that can instead do the mapping /
> unmapping regardless of the context.
> 
> With kmap_local_page(), the mapping is per thread, CPU local and not
> globally visible. Therefore, hmm_store()() is a function where the use
> of kmap_local_page() in place of both kmap() and kmap_atomic() is
> correctly suited.
> 
> Convert the calls of kmap() / kunmap() and kmap_atomic() /
> kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
> unnecessary tests which test if the code is in atomic context.
> 

Not specifically about this patch, but more generally about all
such conversions - is there a 'proof' that shows this just works
or do we need to test each one. If the latter, then how?


> Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
> ---
>  drivers/staging/media/atomisp/pci/hmm/hmm.c | 14 ++------------
>  1 file changed, 2 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm.c b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> index 46ac082cd3f1..54188197c3dc 100644
> --- a/drivers/staging/media/atomisp/pci/hmm/hmm.c
> +++ b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> @@ -482,10 +482,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
>  		idx = (virt - bo->start) >> PAGE_SHIFT;
>  		offset = (virt - bo->start) - (idx << PAGE_SHIFT);
>  
> -		if (in_atomic())
> -			des = (char *)kmap_atomic(bo->page_obj[idx].page);
> -		else
> -			des = (char *)kmap(bo->page_obj[idx].page);
> +		des = (char *)kmap_local_page(bo->page_obj[idx].page);
>  
>  		if (!des) {
>  			dev_err(atomisp_dev,
> @@ -512,14 +509,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
>  
>  		clflush_cache_range(des, len);
>  
> -		if (in_atomic())
> -			/*
> -			 * Note: kunmap_atomic requires return addr from
> -			 * kmap_atomic, not the page. See linux/highmem.h
> -			 */
> -			kunmap_atomic(des - offset);
> -		else
> -			kunmap(bo->page_obj[idx].page);
> +		kunmap_local(des);
>  	}
>  
>  	return 0;
> -- 
> 2.34.1
> 
> 

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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-14  0:44 ` Alison Schofield
@ 2022-04-14  1:54   ` Ira Weiny
  2022-04-14  7:03     ` Julia Lawall
  0 siblings, 1 reply; 12+ messages in thread
From: Ira Weiny @ 2022-04-14  1:54 UTC (permalink / raw)
  To: Alison Schofield
  Cc: Fabio M. De Francesco, Mauro Carvalho Chehab, Sakari Ailus,
	Greg Kroah-Hartman, Hans Verkuil, Tsuchiya Yuto,
	Martiros Shakhzadyan, Hans de Goede, linux-media, linux-staging,
	linux-kernel, outreachy

On Wed, Apr 13, 2022 at 05:44:54PM -0700, Alison Schofield wrote:
> On Thu, Apr 14, 2022 at 12:55:31AM +0200, Fabio M. De Francesco wrote:
> > The use of kmap() is being deprecated in favor of kmap_local_page()
> > where it is feasible. The same is true for kmap_atomic().
> > 
> > In file pci/hmm/hmm.c, function hmm_store() test if we are in atomic
> > context and, if so, it calls kmap_atomic(), if not, it calls kmap().
> > 
> > First of all, in_atomic() shouldn't be used in drivers. This macro
> > cannot always detect atomic context; in particular, it cannot know
> > about held spinlocks in non-preemptible kernels.
> > 
> > Notwithstanding what it is said above, this code doesn't need to care
> > whether or not it is executing in atomic context. It can simply use
> > kmap_local_page() / kunmap_local() that can instead do the mapping /
> > unmapping regardless of the context.
> > 
> > With kmap_local_page(), the mapping is per thread, CPU local and not
> > globally visible. Therefore, hmm_store()() is a function where the use
> > of kmap_local_page() in place of both kmap() and kmap_atomic() is
> > correctly suited.
> > 
> > Convert the calls of kmap() / kunmap() and kmap_atomic() /
> > kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
> > unnecessary tests which test if the code is in atomic context.
> > 
> 
> Not specifically about this patch, but more generally about all
> such conversions - is there a 'proof' that shows this just works

Just code inspection.  Most of them that I have done have been compile tested
only.  Part of the key is that des is a local variable and is not aliased by
anything outside this function.

> or do we need to test each one. If the latter, then how?

Generally there is no test if we don't have the hardware.  Some of the more
difficult conversions will probably need to have some testing done but that
will need to be discussed with the subsystem maintainers at the time.

Ira

> 
> 
> > Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
> > ---
> >  drivers/staging/media/atomisp/pci/hmm/hmm.c | 14 ++------------
> >  1 file changed, 2 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm.c b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> > index 46ac082cd3f1..54188197c3dc 100644
> > --- a/drivers/staging/media/atomisp/pci/hmm/hmm.c
> > +++ b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> > @@ -482,10 +482,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
> >  		idx = (virt - bo->start) >> PAGE_SHIFT;
> >  		offset = (virt - bo->start) - (idx << PAGE_SHIFT);
> >  
> > -		if (in_atomic())
> > -			des = (char *)kmap_atomic(bo->page_obj[idx].page);
> > -		else
> > -			des = (char *)kmap(bo->page_obj[idx].page);
> > +		des = (char *)kmap_local_page(bo->page_obj[idx].page);
> >  
> >  		if (!des) {
> >  			dev_err(atomisp_dev,
> > @@ -512,14 +509,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
> >  
> >  		clflush_cache_range(des, len);
> >  
> > -		if (in_atomic())
> > -			/*
> > -			 * Note: kunmap_atomic requires return addr from
> > -			 * kmap_atomic, not the page. See linux/highmem.h
> > -			 */
> > -			kunmap_atomic(des - offset);
> > -		else
> > -			kunmap(bo->page_obj[idx].page);
> > +		kunmap_local(des);
> >  	}
> >  
> >  	return 0;
> > -- 
> > 2.34.1
> > 
> > 

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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-14  1:54   ` Ira Weiny
@ 2022-04-14  7:03     ` Julia Lawall
  2022-04-14  9:03       ` Fabio M. De Francesco
  0 siblings, 1 reply; 12+ messages in thread
From: Julia Lawall @ 2022-04-14  7:03 UTC (permalink / raw)
  To: Ira Weiny
  Cc: Alison Schofield, Fabio M. De Francesco, Mauro Carvalho Chehab,
	Sakari Ailus, Greg Kroah-Hartman, Hans Verkuil, Tsuchiya Yuto,
	Martiros Shakhzadyan, Hans de Goede, linux-media, linux-staging,
	linux-kernel, outreachy



On Wed, 13 Apr 2022, Ira Weiny wrote:

> On Wed, Apr 13, 2022 at 05:44:54PM -0700, Alison Schofield wrote:
> > On Thu, Apr 14, 2022 at 12:55:31AM +0200, Fabio M. De Francesco wrote:
> > > The use of kmap() is being deprecated in favor of kmap_local_page()
> > > where it is feasible. The same is true for kmap_atomic().
> > >
> > > In file pci/hmm/hmm.c, function hmm_store() test if we are in atomic
> > > context and, if so, it calls kmap_atomic(), if not, it calls kmap().
> > >
> > > First of all, in_atomic() shouldn't be used in drivers. This macro
> > > cannot always detect atomic context; in particular, it cannot know
> > > about held spinlocks in non-preemptible kernels.
> > >
> > > Notwithstanding what it is said above, this code doesn't need to care
> > > whether or not it is executing in atomic context. It can simply use
> > > kmap_local_page() / kunmap_local() that can instead do the mapping /
> > > unmapping regardless of the context.
> > >
> > > With kmap_local_page(), the mapping is per thread, CPU local and not
> > > globally visible. Therefore, hmm_store()() is a function where the use
> > > of kmap_local_page() in place of both kmap() and kmap_atomic() is
> > > correctly suited.
> > >
> > > Convert the calls of kmap() / kunmap() and kmap_atomic() /
> > > kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
> > > unnecessary tests which test if the code is in atomic context.
> > >
> >
> > Not specifically about this patch, but more generally about all
> > such conversions - is there a 'proof' that shows this just works
>
> Just code inspection.  Most of them that I have done have been compile tested
> only.  Part of the key is that des is a local variable and is not aliased by
> anything outside this function.

Typically, the concern about being in atomic context has to do with
whether GFP_KERNEL or GFP_ATOMIC should be used, ie whether allocation can
sleep.  It doesn't have to do with whether some data can be shared.  Is
that the concern here?

julia

>
> > or do we need to test each one. If the latter, then how?
>
> Generally there is no test if we don't have the hardware.  Some of the more
> difficult conversions will probably need to have some testing done but that
> will need to be discussed with the subsystem maintainers at the time.
>
> Ira
>
> >
> >
> > > Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
> > > ---
> > >  drivers/staging/media/atomisp/pci/hmm/hmm.c | 14 ++------------
> > >  1 file changed, 2 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm.c b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> > > index 46ac082cd3f1..54188197c3dc 100644
> > > --- a/drivers/staging/media/atomisp/pci/hmm/hmm.c
> > > +++ b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> > > @@ -482,10 +482,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
> > >  		idx = (virt - bo->start) >> PAGE_SHIFT;
> > >  		offset = (virt - bo->start) - (idx << PAGE_SHIFT);
> > >
> > > -		if (in_atomic())
> > > -			des = (char *)kmap_atomic(bo->page_obj[idx].page);
> > > -		else
> > > -			des = (char *)kmap(bo->page_obj[idx].page);
> > > +		des = (char *)kmap_local_page(bo->page_obj[idx].page);
> > >
> > >  		if (!des) {
> > >  			dev_err(atomisp_dev,
> > > @@ -512,14 +509,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
> > >
> > >  		clflush_cache_range(des, len);
> > >
> > > -		if (in_atomic())
> > > -			/*
> > > -			 * Note: kunmap_atomic requires return addr from
> > > -			 * kmap_atomic, not the page. See linux/highmem.h
> > > -			 */
> > > -			kunmap_atomic(des - offset);
> > > -		else
> > > -			kunmap(bo->page_obj[idx].page);
> > > +		kunmap_local(des);
> > >  	}
> > >
> > >  	return 0;
> > > --
> > > 2.34.1
> > >
> > >
>
>

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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-14  7:03     ` Julia Lawall
@ 2022-04-14  9:03       ` Fabio M. De Francesco
  2022-04-14  9:12         ` Julia Lawall
  0 siblings, 1 reply; 12+ messages in thread
From: Fabio M. De Francesco @ 2022-04-14  9:03 UTC (permalink / raw)
  To: Ira Weiny, Julia Lawall
  Cc: Alison Schofield, Mauro Carvalho Chehab, Sakari Ailus,
	Greg Kroah-Hartman, Hans Verkuil, Tsuchiya Yuto,
	Martiros Shakhzadyan, Hans de Goede, linux-media, linux-staging,
	linux-kernel, outreachy

On gioved? 14 aprile 2022 09:03:40 CEST Julia Lawall wrote:
> 
> On Wed, 13 Apr 2022, Ira Weiny wrote:
> 
> > On Wed, Apr 13, 2022 at 05:44:54PM -0700, Alison Schofield wrote:
> > > On Thu, Apr 14, 2022 at 12:55:31AM +0200, Fabio M. De Francesco 
wrote:
> > > > The use of kmap() is being deprecated in favor of kmap_local_page()
> > > > where it is feasible. The same is true for kmap_atomic().
> > > >
> > > > In file pci/hmm/hmm.c, function hmm_store() test if we are in 
atomic
> > > > context and, if so, it calls kmap_atomic(), if not, it calls 
kmap().
> > > >
> > > > First of all, in_atomic() shouldn't be used in drivers. This macro
> > > > cannot always detect atomic context; in particular, it cannot know
> > > > about held spinlocks in non-preemptible kernels.
> > > >
> > > > Notwithstanding what it is said above, this code doesn't need to 
care
> > > > whether or not it is executing in atomic context. It can simply use
> > > > kmap_local_page() / kunmap_local() that can instead do the mapping 
/
> > > > unmapping regardless of the context.
> > > >
> > > > With kmap_local_page(), the mapping is per thread, CPU local and 
not
> > > > globally visible. Therefore, hmm_store()() is a function where the 
use
> > > > of kmap_local_page() in place of both kmap() and kmap_atomic() is
> > > > correctly suited.
> > > >
> > > > Convert the calls of kmap() / kunmap() and kmap_atomic() /
> > > > kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
> > > > unnecessary tests which test if the code is in atomic context.
> > > >
> > >
> > > Not specifically about this patch, but more generally about all
> > > such conversions - is there a 'proof' that shows this just works
> >
> > Just code inspection.  Most of them that I have done have been compile 
tested
> > only.  Part of the key is that des is a local variable and is not 
aliased by
> > anything outside this function.
> 
> Typically, the concern about being in atomic context has to do with
> whether GFP_KERNEL or GFP_ATOMIC should be used, ie whether allocation 
> can sleep.  

I'd add that the concern about being in atomic context has mainly to do 
with calling whatever function that may sleep. 

Some time ago I analyzed a calls chain which, under spinlocks and with 
IRQ's disabled, led to console_lock() which is annotated with 
might_sleep(). It took about 8000 ms to recover when executing in a 4 CPU / 
8 SMT System. Linus T. suggested to make this work asynchronous (commit 
1ee33b1ca2b8 ("tty: n_hdlc: make n_hdlc_tty_wakeup() asynchronous")).

> It doesn't have to do with whether some data can be shared.  

Yes, FWIW I agree with you.

> Is that the concern here?

The concern here is about the locality of the pointer variable to which the 
struct page has been mapped to. In atomic context we are not allowed to 
kmap() (this is why in the code we had that in_atomic() test), instead we 
can kmap_local_page() or kmap_atomic(). The latter is strongly discouraged 
in favor of the former.

Furthermore, Alison was asking if we can prove that these kinds of 
conversions can actually work when we have not the hardware for testing. As 
Ira wrote, code inspection is sufficient to prove it.

Thanks,

Fabio M. De Francesco




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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-14  9:03       ` Fabio M. De Francesco
@ 2022-04-14  9:12         ` Julia Lawall
  2022-04-14  9:41           ` Fabio M. De Francesco
  0 siblings, 1 reply; 12+ messages in thread
From: Julia Lawall @ 2022-04-14  9:12 UTC (permalink / raw)
  To: Fabio M. De Francesco
  Cc: Ira Weiny, Julia Lawall, Alison Schofield, Mauro Carvalho Chehab,
	Sakari Ailus, Greg Kroah-Hartman, Hans Verkuil, Tsuchiya Yuto,
	Martiros Shakhzadyan, Hans de Goede, linux-media, linux-staging,
	linux-kernel, outreachy



On Thu, 14 Apr 2022, Fabio M. De Francesco wrote:

> On gioved? 14 aprile 2022 09:03:40 CEST Julia Lawall wrote:
> >
> > On Wed, 13 Apr 2022, Ira Weiny wrote:
> >
> > > On Wed, Apr 13, 2022 at 05:44:54PM -0700, Alison Schofield wrote:
> > > > On Thu, Apr 14, 2022 at 12:55:31AM +0200, Fabio M. De Francesco
> wrote:
> > > > > The use of kmap() is being deprecated in favor of kmap_local_page()
> > > > > where it is feasible. The same is true for kmap_atomic().
> > > > >
> > > > > In file pci/hmm/hmm.c, function hmm_store() test if we are in
> atomic
> > > > > context and, if so, it calls kmap_atomic(), if not, it calls
> kmap().
> > > > >
> > > > > First of all, in_atomic() shouldn't be used in drivers. This macro
> > > > > cannot always detect atomic context; in particular, it cannot know
> > > > > about held spinlocks in non-preemptible kernels.
> > > > >
> > > > > Notwithstanding what it is said above, this code doesn't need to
> care
> > > > > whether or not it is executing in atomic context. It can simply use
> > > > > kmap_local_page() / kunmap_local() that can instead do the mapping
> /
> > > > > unmapping regardless of the context.
> > > > >
> > > > > With kmap_local_page(), the mapping is per thread, CPU local and
> not
> > > > > globally visible. Therefore, hmm_store()() is a function where the
> use
> > > > > of kmap_local_page() in place of both kmap() and kmap_atomic() is
> > > > > correctly suited.
> > > > >
> > > > > Convert the calls of kmap() / kunmap() and kmap_atomic() /
> > > > > kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
> > > > > unnecessary tests which test if the code is in atomic context.
> > > > >
> > > >
> > > > Not specifically about this patch, but more generally about all
> > > > such conversions - is there a 'proof' that shows this just works
> > >
> > > Just code inspection.  Most of them that I have done have been compile
> tested
> > > only.  Part of the key is that des is a local variable and is not
> aliased by
> > > anything outside this function.
> >
> > Typically, the concern about being in atomic context has to do with
> > whether GFP_KERNEL or GFP_ATOMIC should be used, ie whether allocation
> > can sleep.
>
> I'd add that the concern about being in atomic context has mainly to do
> with calling whatever function that may sleep.
>
> Some time ago I analyzed a calls chain which, under spinlocks and with
> IRQ's disabled, led to console_lock() which is annotated with
> might_sleep(). It took about 8000 ms to recover when executing in a 4 CPU /
> 8 SMT System. Linus T. suggested to make this work asynchronous (commit
> 1ee33b1ca2b8 ("tty: n_hdlc: make n_hdlc_tty_wakeup() asynchronous")).
>
> > It doesn't have to do with whether some data can be shared.
>
> Yes, FWIW I agree with you.
>
> > Is that the concern here?
>
> The concern here is about the locality of the pointer variable to which the
> struct page has been mapped to. In atomic context we are not allowed to
> kmap() (this is why in the code we had that in_atomic() test), instead we
> can kmap_local_page() or kmap_atomic(). The latter is strongly discouraged
> in favor of the former.

I have the impression that you are first agreeing with me and then
contradicting me :).  Is your point that in general a concern about atomic
context has to do with whether sleeping is allowed, but that the concern
is something else here?  I'm not familiar with these kmap functions.

thanks,
julia


>
> Furthermore, Alison was asking if we can prove that these kinds of
> conversions can actually work when we have not the hardware for testing. As
> Ira wrote, code inspection is sufficient to prove it.
>
> Thanks,
>
> Fabio M. De Francesco
>
>
>
>

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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-14  9:12         ` Julia Lawall
@ 2022-04-14  9:41           ` Fabio M. De Francesco
  0 siblings, 0 replies; 12+ messages in thread
From: Fabio M. De Francesco @ 2022-04-14  9:41 UTC (permalink / raw)
  To: Julia Lawall
  Cc: Ira Weiny, Julia Lawall, Alison Schofield, Mauro Carvalho Chehab,
	Sakari Ailus, Greg Kroah-Hartman, Hans Verkuil, Tsuchiya Yuto,
	Martiros Shakhzadyan, Hans de Goede, linux-media, linux-staging,
	linux-kernel, outreachy

On gioved? 14 aprile 2022 11:12:39 CEST Julia Lawall wrote:
> 
> On Thu, 14 Apr 2022, Fabio M. De Francesco wrote:
> 
> > On gioved? 14 aprile 2022 09:03:40 CEST Julia Lawall wrote:
> > >
> > > On Wed, 13 Apr 2022, Ira Weiny wrote:
> > >
> > > > On Wed, Apr 13, 2022 at 05:44:54PM -0700, Alison Schofield wrote:
> > > > > On Thu, Apr 14, 2022 at 12:55:31AM +0200, Fabio M. De Francesco
> > wrote:
> > > > > > The use of kmap() is being deprecated in favor of 
kmap_local_page()
> > > > > > where it is feasible. The same is true for kmap_atomic().
> > > > > >
> > > > > > In file pci/hmm/hmm.c, function hmm_store() test if we are in
> > atomic
> > > > > > context and, if so, it calls kmap_atomic(), if not, it calls
> > kmap().
> > > > > >
> > > > > > First of all, in_atomic() shouldn't be used in drivers. This 
macro
> > > > > > cannot always detect atomic context; in particular, it cannot 
know
> > > > > > about held spinlocks in non-preemptible kernels.
> > > > > >
> > > > > > Notwithstanding what it is said above, this code doesn't need 
to
> > care
> > > > > > whether or not it is executing in atomic context. It can simply 
use
> > > > > > kmap_local_page() / kunmap_local() that can instead do the 
mapping
> > /
> > > > > > unmapping regardless of the context.
> > > > > >
> > > > > > With kmap_local_page(), the mapping is per thread, CPU local 
and
> > not
> > > > > > globally visible. Therefore, hmm_store()() is a function where 
the
> > use
> > > > > > of kmap_local_page() in place of both kmap() and kmap_atomic() 
is
> > > > > > correctly suited.
> > > > > >
> > > > > > Convert the calls of kmap() / kunmap() and kmap_atomic() /
> > > > > > kunmap_atomic() to kmap_local_page() / kunmap_local() and drop 
the
> > > > > > unnecessary tests which test if the code is in atomic context.
> > > > > >
> > > > >
> > > > > Not specifically about this patch, but more generally about all
> > > > > such conversions - is there a 'proof' that shows this just works
> > > >
> > > > Just code inspection.  Most of them that I have done have been 
compile
> > tested
> > > > only.  Part of the key is that des is a local variable and is not
> > aliased by
> > > > anything outside this function.
> > >
> > > Typically, the concern about being in atomic context has to do with
> > > whether GFP_KERNEL or GFP_ATOMIC should be used, ie whether 
allocation
> > > can sleep.
> >
> > I'd add that the concern about being in atomic context has mainly to do
> > with calling whatever function that may sleep.
> >
> > Some time ago I analyzed a calls chain which, under spinlocks and with
> > IRQ's disabled, led to console_lock() which is annotated with
> > might_sleep(). It took about 8000 ms to recover when executing in a 4 
CPU /
> > 8 SMT System. Linus T. suggested to make this work asynchronous (commit
> > 1ee33b1ca2b8 ("tty: n_hdlc: make n_hdlc_tty_wakeup() asynchronous")).
> >
> > > It doesn't have to do with whether some data can be shared.
> >
> > Yes, FWIW I agree with you.
> >
> > > Is that the concern here?
> >
> > The concern here is about the locality of the pointer variable to which 
the
> > struct page has been mapped to. In atomic context we are not allowed to
> > kmap() (this is why in the code we had that in_atomic() test), instead 
we
> > can kmap_local_page() or kmap_atomic(). The latter is strongly 
discouraged
> > in favor of the former.
> 
> I have the impression that you are first agreeing with me and then
> contradicting me :).  Is your point that in general a concern about 
atomic
> context has to do with whether sleeping is allowed, but that the concern
> is something else here?  I'm not familiar with these kmap functions.

Yes the concern is something else here (sorry for my poor English). It was 
not my intention to contradict you :) 

The concern for "locality" here is that if the variable is shared between 
different functions there are cases where we cannot use kmap_local_page().
For example, those mappings with kmap_local_page() are per thread and CPU 
local.

I think that the best means to convey what I want to express is pointing to 
my patch to Documentation/vm/highmem.rst:

https://lore.kernel.org/lkml/20220412124003.10736-1-fmdefrancesco@gmail.com/

I hope that this can help to understand why we care of "locality" in this 
specific case where we use kmap_local_page().

Again, sorry for not being clear.

Thanks,

Fabio M. De Francesco

> thanks,
> julia
> 
> 
> >
> > Furthermore, Alison was asking if we can prove that these kinds of
> > conversions can actually work when we have not the hardware for 
testing. As
> > Ira wrote, code inspection is sufficient to prove it.
> >
> > Thanks,
> >
> > Fabio M. De Francesco




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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-13 22:55 [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store() Fabio M. De Francesco
  2022-04-14  0:44 ` Alison Schofield
@ 2022-04-15  0:37 ` Ira Weiny
  2022-04-15  1:08   ` Fabio M. De Francesco
  2022-04-20 11:07 ` Hans de Goede
  2022-04-25 18:29 ` Fabio M. De Francesco
  3 siblings, 1 reply; 12+ messages in thread
From: Ira Weiny @ 2022-04-15  0:37 UTC (permalink / raw)
  To: Fabio M. De Francesco
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Greg Kroah-Hartman,
	Hans Verkuil, Tsuchiya Yuto, Martiros Shakhzadyan, Hans de Goede,
	linux-media, linux-staging, linux-kernel, outreachy

On Thu, Apr 14, 2022 at 12:55:31AM +0200, Fabio M. De Francesco wrote:
> The use of kmap() is being deprecated in favor of kmap_local_page()
> where it is feasible. The same is true for kmap_atomic().
> 
> In file pci/hmm/hmm.c, function hmm_store() test if we are in atomic
> context and, if so, it calls kmap_atomic(), if not, it calls kmap().
> 
> First of all, in_atomic() shouldn't be used in drivers. This macro
> cannot always detect atomic context; in particular, it cannot know
> about held spinlocks in non-preemptible kernels.
> 
> Notwithstanding what it is said above, this code doesn't need to care
> whether or not it is executing in atomic context. It can simply use
> kmap_local_page() / kunmap_local() that can instead do the mapping /
> unmapping regardless of the context.
> 
> With kmap_local_page(), the mapping is per thread, CPU local and not
> globally visible. Therefore, hmm_store()() is a function where the use
> of kmap_local_page() in place of both kmap() and kmap_atomic() is
> correctly suited.
> 
> Convert the calls of kmap() / kunmap() and kmap_atomic() /
> kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
> unnecessary tests which test if the code is in atomic context.
> 
> Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>

I've had to research this a bit myself because I've not seen this pattern
before.

kmap_atomic() had 2 uses:

	1) a situation where the operation on the page requires pagefaults
	   and/or preemption to be disabled
	2) in a situation where one knows the code can't sleep

kmap_local_page() removes the second use case because kmap() is no longer the
only alternative; from the kdoc for kmap_atomic():

...
 * kmap_atomic - Atomically map a page for temporary usage - Deprecated!
...
 * Effectively a wrapper around kmap_local_page() which disables pagefaults
 * and preemption.
...

The deprecation is because any pagefault/preemption disabling should probably
be done explicitly from now on but allows for existing kmap_atomic() callers to
live on.

In this case, I suspect the original driver writer wanted to use kmap() but
hmm_store() was called from various contexts.  So they incorrectly tried to
protect against the (potentially) sleeping kmap() call.  In reality, I think
they could have simply called kmap_atomic() and skipped 'in_atomic()' check
altogether.

Regardless now that kmap_local_page() exists, this is correct.

Reviewed-by: Ira Weiny <ira.weiny@intel.com>

> ---
>  drivers/staging/media/atomisp/pci/hmm/hmm.c | 14 ++------------
>  1 file changed, 2 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm.c b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> index 46ac082cd3f1..54188197c3dc 100644
> --- a/drivers/staging/media/atomisp/pci/hmm/hmm.c
> +++ b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> @@ -482,10 +482,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
>  		idx = (virt - bo->start) >> PAGE_SHIFT;
>  		offset = (virt - bo->start) - (idx << PAGE_SHIFT);
>  
> -		if (in_atomic())
> -			des = (char *)kmap_atomic(bo->page_obj[idx].page);
> -		else
> -			des = (char *)kmap(bo->page_obj[idx].page);
> +		des = (char *)kmap_local_page(bo->page_obj[idx].page);
>  
>  		if (!des) {
>  			dev_err(atomisp_dev,
> @@ -512,14 +509,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
>  
>  		clflush_cache_range(des, len);
>  
> -		if (in_atomic())
> -			/*
> -			 * Note: kunmap_atomic requires return addr from
> -			 * kmap_atomic, not the page. See linux/highmem.h
> -			 */
> -			kunmap_atomic(des - offset);
> -		else
> -			kunmap(bo->page_obj[idx].page);
> +		kunmap_local(des);
>  	}
>  
>  	return 0;
> -- 
> 2.34.1
> 

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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-15  0:37 ` Ira Weiny
@ 2022-04-15  1:08   ` Fabio M. De Francesco
  0 siblings, 0 replies; 12+ messages in thread
From: Fabio M. De Francesco @ 2022-04-15  1:08 UTC (permalink / raw)
  To: Ira Weiny
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Greg Kroah-Hartman,
	Hans Verkuil, Tsuchiya Yuto, Martiros Shakhzadyan, Hans de Goede,
	linux-media, linux-staging, linux-kernel, outreachy

On venerd? 15 aprile 2022 02:37:27 CEST Ira Weiny wrote:

> Regardless now that kmap_local_page() exists, this is correct.
> 
> Reviewed-by: Ira Weiny <ira.weiny@intel.com>

I'm pretty sure this particular patch would have had a hard time getting 
accepted without any authoritative "Reviewed-by" tag from you or other 
people more experienced than me.

Thank you very much!

Fabio M. De Francesco



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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-13 22:55 [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store() Fabio M. De Francesco
  2022-04-14  0:44 ` Alison Schofield
  2022-04-15  0:37 ` Ira Weiny
@ 2022-04-20 11:07 ` Hans de Goede
  2022-04-25 18:29 ` Fabio M. De Francesco
  3 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2022-04-20 11:07 UTC (permalink / raw)
  To: Fabio M. De Francesco, Mauro Carvalho Chehab, Sakari Ailus,
	Greg Kroah-Hartman, Hans Verkuil, Tsuchiya Yuto,
	Martiros Shakhzadyan, linux-media, linux-staging, linux-kernel,
	Ira Weiny, outreachy

Hi,

On 4/14/22 00:55, Fabio M. De Francesco wrote:
> The use of kmap() is being deprecated in favor of kmap_local_page()
> where it is feasible. The same is true for kmap_atomic().
> 
> In file pci/hmm/hmm.c, function hmm_store() test if we are in atomic
> context and, if so, it calls kmap_atomic(), if not, it calls kmap().
> 
> First of all, in_atomic() shouldn't be used in drivers. This macro
> cannot always detect atomic context; in particular, it cannot know
> about held spinlocks in non-preemptible kernels.
> 
> Notwithstanding what it is said above, this code doesn't need to care
> whether or not it is executing in atomic context. It can simply use
> kmap_local_page() / kunmap_local() that can instead do the mapping /
> unmapping regardless of the context.
> 
> With kmap_local_page(), the mapping is per thread, CPU local and not
> globally visible. Therefore, hmm_store()() is a function where the use
> of kmap_local_page() in place of both kmap() and kmap_atomic() is
> correctly suited.
> 
> Convert the calls of kmap() / kunmap() and kmap_atomic() /
> kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
> unnecessary tests which test if the code is in atomic context.
> 
> Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>


I've successfully tested this on both the front and back cams
of a chuwi hi8 tablet:

Tested-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans



> ---
>  drivers/staging/media/atomisp/pci/hmm/hmm.c | 14 ++------------
>  1 file changed, 2 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm.c b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> index 46ac082cd3f1..54188197c3dc 100644
> --- a/drivers/staging/media/atomisp/pci/hmm/hmm.c
> +++ b/drivers/staging/media/atomisp/pci/hmm/hmm.c
> @@ -482,10 +482,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
>  		idx = (virt - bo->start) >> PAGE_SHIFT;
>  		offset = (virt - bo->start) - (idx << PAGE_SHIFT);
>  
> -		if (in_atomic())
> -			des = (char *)kmap_atomic(bo->page_obj[idx].page);
> -		else
> -			des = (char *)kmap(bo->page_obj[idx].page);
> +		des = (char *)kmap_local_page(bo->page_obj[idx].page);
>  
>  		if (!des) {
>  			dev_err(atomisp_dev,
> @@ -512,14 +509,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes)
>  
>  		clflush_cache_range(des, len);
>  
> -		if (in_atomic())
> -			/*
> -			 * Note: kunmap_atomic requires return addr from
> -			 * kmap_atomic, not the page. See linux/highmem.h
> -			 */
> -			kunmap_atomic(des - offset);
> -		else
> -			kunmap(bo->page_obj[idx].page);
> +		kunmap_local(des);
>  	}
>  
>  	return 0;


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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-13 22:55 [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store() Fabio M. De Francesco
                   ` (2 preceding siblings ...)
  2022-04-20 11:07 ` Hans de Goede
@ 2022-04-25 18:29 ` Fabio M. De Francesco
  2022-04-29 13:46   ` Fabio M. De Francesco
  3 siblings, 1 reply; 12+ messages in thread
From: Fabio M. De Francesco @ 2022-04-25 18:29 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Sakari Ailus, Greg Kroah-Hartman, Hans Verkuil, Tsuchiya Yuto,
	Martiros Shakhzadyan, Hans de Goede, linux-media, linux-staging,
	linux-kernel, Ira Weiny, outreachy

On giovedì 14 aprile 2022 00:55:31 CEST Fabio M. De Francesco wrote:
> The use of kmap() is being deprecated in favor of kmap_local_page()
> where it is feasible. The same is true for kmap_atomic().
> 
> In file pci/hmm/hmm.c, function hmm_store() test if we are in atomic
> context and, if so, it calls kmap_atomic(), if not, it calls kmap().
> 
> First of all, in_atomic() shouldn't be used in drivers. This macro
> cannot always detect atomic context; in particular, it cannot know
> about held spinlocks in non-preemptible kernels.
> 
> Notwithstanding what it is said above, this code doesn't need to care
> whether or not it is executing in atomic context. It can simply use
> kmap_local_page() / kunmap_local() that can instead do the mapping /
> unmapping regardless of the context.
> 
> With kmap_local_page(), the mapping is per thread, CPU local and not
> globally visible. Therefore, hmm_store()() is a function where the use
> of kmap_local_page() in place of both kmap() and kmap_atomic() is
> correctly suited.
> 
> Convert the calls of kmap() / kunmap() and kmap_atomic() /
> kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
> unnecessary tests which test if the code is in atomic context.
> 
> Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
> ---
>  drivers/staging/media/atomisp/pci/hmm/hmm.c | 14 ++------------
>  1 file changed, 2 insertions(+), 12 deletions(-)

Hi Mauro,

I'm writing for just a gentle ping for this and two other staging/atomisp/ 
patches that still seem to be waiting to be applied.

In the meantime I would like to remind you that Hans de Goede has 
successfully tested this patch and the other two on both the front and back 
cams of a chuwi hi8 tablet.

Please let me know if there is anything else that is required to be done in 
order to accept the three patches.

Thanks,

Fabio M. De Francesco



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

* Re: [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
  2022-04-25 18:29 ` Fabio M. De Francesco
@ 2022-04-29 13:46   ` Fabio M. De Francesco
  0 siblings, 0 replies; 12+ messages in thread
From: Fabio M. De Francesco @ 2022-04-29 13:46 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Tsuchiya Yuto
  Cc: Sakari Ailus, Greg Kroah-Hartman, Martiros Shakhzadyan,
	Hans de Goede, linux-media, linux-staging, linux-kernel,
	Ira Weiny, outreachy

On lunedì 25 aprile 2022 20:29:03 CEST Fabio M. De Francesco wrote:
> On giovedì 14 aprile 2022 00:55:31 CEST Fabio M. De Francesco wrote:
> > The use of kmap() is being deprecated in favor of kmap_local_page()
> > where it is feasible. The same is true for kmap_atomic().
> > 
> > In file pci/hmm/hmm.c, function hmm_store() test if we are in atomic
> > context and, if so, it calls kmap_atomic(), if not, it calls kmap().
> > 
> > First of all, in_atomic() shouldn't be used in drivers. This macro
> > cannot always detect atomic context; in particular, it cannot know
> > about held spinlocks in non-preemptible kernels.
> > 
> > Notwithstanding what it is said above, this code doesn't need to care
> > whether or not it is executing in atomic context. It can simply use
> > kmap_local_page() / kunmap_local() that can instead do the mapping /
> > unmapping regardless of the context.
> > 
> > With kmap_local_page(), the mapping is per thread, CPU local and not
> > globally visible. Therefore, hmm_store()() is a function where the use
> > of kmap_local_page() in place of both kmap() and kmap_atomic() is
> > correctly suited.
> > 
> > Convert the calls of kmap() / kunmap() and kmap_atomic() /
> > kunmap_atomic() to kmap_local_page() / kunmap_local() and drop the
> > unnecessary tests which test if the code is in atomic context.
> > 
> > Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
> > ---
> >  drivers/staging/media/atomisp/pci/hmm/hmm.c | 14 ++------------
> >  1 file changed, 2 insertions(+), 12 deletions(-)
> 
> Hi Mauro,
> 
> I'm writing for just a gentle ping for this and two other staging/
atomisp/ 
> patches that still seem to be waiting to be applied.
> 
> In the meantime I would like to remind you that Hans de Goede has 
> successfully tested this patch and the other two on both the front and 
back 
> cams of a chuwi hi8 tablet.

Hi Mauro,

In my previous message I forgot to remind you that two of these three 
patches have also been reviewed by Ira Weiny (Intel).

I'd like to ask you again if there is still something left which prevents 
these three patches from being accepted. The first of the three patches was 
submitted on April 9, 2022.

For you convenience here are the links to the patches, the "Reviewed-by:" 
and "Tested-by:" tags:

[PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store()
https://lore.kernel.org/lkml/20220413225531.9425-1-fmdefrancesco@gmail.com/
https://lore.kernel.org/lkml/Yli+R7iLZKqO8kVP@iweiny-desk3/
https://lore.kernel.org/lkml/2d096f20-dbaa-1d49-96e9-a7ae6c19f7fe@redhat.com/

[PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_set()
https://lore.kernel.org/lkml/20220413212210.18494-1-fmdefrancesco@gmail.com/
https://lore.kernel.org/lkml/YldNhErgt53RqYp7@iweiny-desk3/
https://lore.kernel.org/lkml/0b04ad1a-e442-1728-ef2c-bab386a4c64c@redhat.com/

[PATCH] staging: media: atomisp: Convert kmap() to kmap_local_page()
https://lore.kernel.org/lkml/20220408223129.3844-1-fmdefrancesco@gmail.com/
https://lore.kernel.org/lkml/b0aed731-b56f-4378-b50e-fc0cbccbdb84@redhat.com/

Thanks,

Fabio M. De Francesco

P.S.: Do you want me to resend them all and add the above-mentioned tags?




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

end of thread, other threads:[~2022-04-29 13:46 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-13 22:55 [PATCH] staging: media: atomisp: Use kmap_local_page() in hmm_store() Fabio M. De Francesco
2022-04-14  0:44 ` Alison Schofield
2022-04-14  1:54   ` Ira Weiny
2022-04-14  7:03     ` Julia Lawall
2022-04-14  9:03       ` Fabio M. De Francesco
2022-04-14  9:12         ` Julia Lawall
2022-04-14  9:41           ` Fabio M. De Francesco
2022-04-15  0:37 ` Ira Weiny
2022-04-15  1:08   ` Fabio M. De Francesco
2022-04-20 11:07 ` Hans de Goede
2022-04-25 18:29 ` Fabio M. De Francesco
2022-04-29 13:46   ` Fabio M. De Francesco

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).