mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-08 00:29:36 -04:00
dm vdo uds-threads: push 'barrier' down to sparse-cache
The sparse-cache is the only user of the 'barrier' data structure, so just move it private to it. Signed-off-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Matthew Sakai <msakai@redhat.com>
This commit is contained in:
@@ -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"
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user