nscd: bump GC cycle during cache pruning (bug 26130)

Message ID mvm1rjb9ezq.fsf@suse.de
State New
Headers show
Series
  • nscd: bump GC cycle during cache pruning (bug 26130)
Related show

Commit Message

Andreas Schwab Sept. 9, 2020, 2:55 p.m.
While nscd prunes a cache it becomes inconsistent temporarily, which is
visible to clients if that cache is shared.  Bump the GC cycle counter so
that the clients notice the modification window.

Uniformly use atomic_fetch_add to modify the GC cycle counter.
---
 nscd/cache.c | 9 +++++++++
 nscd/mem.c   | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)

-- 
2.28.0


-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

Comments

Adhemerval Zanella via Libc-alpha Sept. 9, 2020, 6:43 p.m. | #1
On 09/09/2020 11:55, Andreas Schwab wrote:
> While nscd prunes a cache it becomes inconsistent temporarily, which is

> visible to clients if that cache is shared.  Bump the GC cycle counter so

> that the clients notice the modification window.

> 

> Uniformly use atomic_fetch_add to modify the GC cycle counter.

> ---

>  nscd/cache.c | 9 +++++++++

>  nscd/mem.c   | 4 ++--

>  2 files changed, 11 insertions(+), 2 deletions(-)

> 

> diff --git a/nscd/cache.c b/nscd/cache.c

> index 94163d9ce3..c0b9b4da3d 100644

> --- a/nscd/cache.c

> +++ b/nscd/cache.c

> @@ -453,6 +453,11 @@ prune_cache (struct database_dyn *table, time_t now, int fd)

>  	  pthread_rwlock_wrlock (&table->lock);

>  	}

>  

> +      /* Now we start modifying the data.  Make sure all readers of the

> +	 data are aware of this and temporarily don't use the data.  */

> +      atomic_fetch_add_relaxed (&table->head->gc_cycle, 1);

> +      assert ((table->head->gc_cycle & 1) == 1);

> +



Is a relaxed atomic suffice here? Other accesses are not done with atomic
at all, so I am not sure how well defined are the 'gc_cycle' usage.

>        while (first <= last)

>  	{

>  	  if (mark[first])

> @@ -493,6 +498,10 @@ prune_cache (struct database_dyn *table, time_t now, int fd)

>  	  ++first;

>  	}

>  

> +      /* Now we are done modifying the data.  */

> +      atomic_fetch_add_relaxed (&table->head->gc_cycle, 1);

> +      assert ((table->head->gc_cycle & 1) == 0);

> +

>        /* It's all done.  */

>        pthread_rwlock_unlock (&table->lock);

>  

> diff --git a/nscd/mem.c b/nscd/mem.c

> index 3d10bb9b46..de5bd12db5 100644

> --- a/nscd/mem.c

> +++ b/nscd/mem.c

> @@ -264,7 +264,7 @@ gc (struct database_dyn *db)

>  

>    /* Now we start modifying the data.  Make sure all readers of the

>       data are aware of this and temporarily don't use the data.  */

> -  ++db->head->gc_cycle;

> +  atomic_fetch_add_relaxed (&db->head->gc_cycle, 1);

>    assert ((db->head->gc_cycle & 1) == 1);

>  

>  

> @@ -490,7 +490,7 @@ gc (struct database_dyn *db)

>  

>  

>    /* Now we are done modifying the data.  */

> -  ++db->head->gc_cycle;

> +  atomic_fetch_add_relaxed (&db->head->gc_cycle, 1);

>    assert ((db->head->gc_cycle & 1) == 0);

>  

>    /* We are done.  */

>
Andreas Schwab Sept. 10, 2020, 8:46 a.m. | #2
On Sep 09 2020, Adhemerval Zanella wrote:

> Is a relaxed atomic suffice here?


I don't really know.

> Other accesses are not done with atomic at all, so I am not sure how

> well defined are the 'gc_cycle' usage.


It won't be worse the the current state, will it?

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
Adhemerval Zanella via Libc-alpha Sept. 10, 2020, 9:58 a.m. | #3
* Andreas Schwab:

> On Sep 09 2020, Adhemerval Zanella wrote:

>

>> Is a relaxed atomic suffice here?

>

> I don't really know.

>

>> Other accesses are not done with atomic at all, so I am not sure how

>> well defined are the 'gc_cycle' usage.

>

> It won't be worse the the current state, will it?


I think that's true, but in the past, Carlos and Torvald both objected
very strongly to partial improvements in code suffering from concurrency
issues.  I'd say give them a few days to comment, and commit your patch
some time next week.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill

Patch

diff --git a/nscd/cache.c b/nscd/cache.c
index 94163d9ce3..c0b9b4da3d 100644
--- a/nscd/cache.c
+++ b/nscd/cache.c
@@ -453,6 +453,11 @@  prune_cache (struct database_dyn *table, time_t now, int fd)
 	  pthread_rwlock_wrlock (&table->lock);
 	}
 
+      /* Now we start modifying the data.  Make sure all readers of the
+	 data are aware of this and temporarily don't use the data.  */
+      atomic_fetch_add_relaxed (&table->head->gc_cycle, 1);
+      assert ((table->head->gc_cycle & 1) == 1);
+
       while (first <= last)
 	{
 	  if (mark[first])
@@ -493,6 +498,10 @@  prune_cache (struct database_dyn *table, time_t now, int fd)
 	  ++first;
 	}
 
+      /* Now we are done modifying the data.  */
+      atomic_fetch_add_relaxed (&table->head->gc_cycle, 1);
+      assert ((table->head->gc_cycle & 1) == 0);
+
       /* It's all done.  */
       pthread_rwlock_unlock (&table->lock);
 
diff --git a/nscd/mem.c b/nscd/mem.c
index 3d10bb9b46..de5bd12db5 100644
--- a/nscd/mem.c
+++ b/nscd/mem.c
@@ -264,7 +264,7 @@  gc (struct database_dyn *db)
 
   /* Now we start modifying the data.  Make sure all readers of the
      data are aware of this and temporarily don't use the data.  */
-  ++db->head->gc_cycle;
+  atomic_fetch_add_relaxed (&db->head->gc_cycle, 1);
   assert ((db->head->gc_cycle & 1) == 1);
 
 
@@ -490,7 +490,7 @@  gc (struct database_dyn *db)
 
 
   /* Now we are done modifying the data.  */
-  ++db->head->gc_cycle;
+  atomic_fetch_add_relaxed (&db->head->gc_cycle, 1);
   assert ((db->head->gc_cycle & 1) == 0);
 
   /* We are done.  */