Skip to content

Commit

Permalink
dm vdo uds-threads: push 'barrier' down to sparse-cache
Browse files Browse the repository at this point in the history
The sparse-cache is the only user of the 'barrier' data structure,
so just move it private to it.

Signed-off-by: Mike Snitzer <[email protected]>
Signed-off-by: Matthew Sakai <[email protected]>
  • Loading branch information
Mike Snitzer authored and lorelei-sakai committed Feb 15, 2024
1 parent dddc651 commit d8002f4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 72 deletions.
69 changes: 68 additions & 1 deletion drivers/md/dm-vdo/sparse-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "sparse-cache.h"

#include <linux/cache.h>
#include <linux/delay.h>
#include <linux/dm-bufio.h>

#include "chapter-index.h"
Expand All @@ -14,7 +15,6 @@
#include "logger.h"
#include "memory-alloc.h"
#include "permassert.h"
#include "uds-threads.h"

/*
* Since the cache is small, it is implemented as a simple array of cache entries. Searching for a
Expand Down Expand Up @@ -141,6 +141,17 @@ struct search_list {
struct cached_chapter_index *entries[];
};

struct barrier {
/* Lock for this barrier object */
struct semaphore lock;
/* Semaphore for threads waiting at this barrier */
struct semaphore wait;
/* Number of threads which have arrived */
int arrived;
/* Total number of threads using this barrier */
int thread_count;
};

struct sparse_cache {
const struct index_geometry *geometry;
unsigned int capacity;
Expand All @@ -156,6 +167,62 @@ struct sparse_cache {
struct cached_chapter_index chapters[];
};

static int uds_initialize_barrier(struct barrier *barrier, unsigned int thread_count)
{
sema_init(&barrier->lock, 1);
barrier->arrived = 0;
barrier->thread_count = thread_count;
sema_init(&barrier->wait, 0);

return UDS_SUCCESS;
}

static int uds_destroy_barrier(struct barrier *barrier)
{
return UDS_SUCCESS;
}

static inline void __down(struct semaphore *semaphore)
{
/*
* Do not use down(semaphore). Instead use down_interruptible so that
* we do not get 120 second stall messages in kern.log.
*/
while (down_interruptible(semaphore) != 0) {
/*
* If we're called from a user-mode process (e.g., "dmsetup
* remove") while waiting for an operation that may take a
* while (e.g., UDS index save), and a signal is sent (SIGINT,
* SIGUSR2), then down_interruptible will not block. If that
* happens, sleep briefly to avoid keeping the CPU locked up in
* this loop. We could just call cond_resched, but then we'd
* still keep consuming CPU time slices and swamp other threads
* trying to do computational work. [VDO-4980]
*/
fsleep(1000);
}
}

static int uds_enter_barrier(struct barrier *barrier)
{
__down(&barrier->lock);
if (++barrier->arrived == barrier->thread_count) {
/* last thread */
int i;

for (i = 1; i < barrier->thread_count; i++)
up(&barrier->wait);

barrier->arrived = 0;
up(&barrier->lock);
} else {
up(&barrier->lock);
__down(&barrier->wait);
}

return UDS_SUCCESS;
}

static int __must_check initialize_cached_chapter_index(struct cached_chapter_index *chapter,
const struct index_geometry *geometry)
{
Expand Down
56 changes: 0 additions & 56 deletions drivers/md/dm-vdo/uds-threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,59 +135,3 @@ int uds_join_threads(struct thread *thread)
uds_free(thread);
return UDS_SUCCESS;
}

static inline void __down(struct semaphore *semaphore)
{
/*
* Do not use down(semaphore). Instead use down_interruptible so that
* we do not get 120 second stall messages in kern.log.
*/
while (down_interruptible(semaphore) != 0) {
/*
* If we're called from a user-mode process (e.g., "dmsetup
* remove") while waiting for an operation that may take a
* while (e.g., UDS index save), and a signal is sent (SIGINT,
* SIGUSR2), then down_interruptible will not block. If that
* happens, sleep briefly to avoid keeping the CPU locked up in
* this loop. We could just call cond_resched, but then we'd
* still keep consuming CPU time slices and swamp other threads
* trying to do computational work. [VDO-4980]
*/
fsleep(1000);
}
}

int uds_initialize_barrier(struct barrier *barrier, unsigned int thread_count)
{
sema_init(&barrier->lock, 1);
barrier->arrived = 0;
barrier->thread_count = thread_count;
sema_init(&barrier->wait, 0);

return UDS_SUCCESS;
}

int uds_destroy_barrier(struct barrier *barrier)
{
return UDS_SUCCESS;
}

int uds_enter_barrier(struct barrier *barrier)
{
__down(&barrier->lock);
if (++barrier->arrived == barrier->thread_count) {
/* last thread */
int i;

for (i = 1; i < barrier->thread_count; i++)
up(&barrier->wait);

barrier->arrived = 0;
up(&barrier->lock);
} else {
up(&barrier->lock);
__down(&barrier->wait);
}

return UDS_SUCCESS;
}
15 changes: 0 additions & 15 deletions drivers/md/dm-vdo/uds-threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ struct cond_var {

struct thread;

struct barrier {
/* Lock for this barrier object */
struct semaphore lock;
/* Semaphore for threads waiting at the barrier */
struct semaphore wait;
/* Number of threads which have arrived */
int arrived;
/* Total number of threads using this barrier */
int thread_count;
};

int __must_check uds_create_thread(void (*thread_function)(void *), void *thread_data,
const char *name, struct thread **new_thread);
Expand All @@ -42,11 +32,6 @@ void uds_perform_once(atomic_t *once_state, void (*function) (void));

int uds_join_threads(struct thread *thread);

int __must_check uds_initialize_barrier(struct barrier *barrier,
unsigned int thread_count);
int uds_destroy_barrier(struct barrier *barrier);
int uds_enter_barrier(struct barrier *barrier);

int __must_check uds_init_cond(struct cond_var *cond);
int uds_signal_cond(struct cond_var *cond);
int uds_broadcast_cond(struct cond_var *cond);
Expand Down

0 comments on commit d8002f4

Please sign in to comment.