mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-03 07:45:17 +00:00
Gather futex helpers into lock.h
Based-on-patch-from: Andrey Vagin <avagin@openvz.org> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Acked-by: Andrey Vagin <avagin@openvz.org>
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
#include "restorer.h"
|
#include "restorer.h"
|
||||||
#include "sockets.h"
|
#include "sockets.h"
|
||||||
|
#include "lock.h"
|
||||||
|
|
||||||
#include "crtools.h"
|
#include "crtools.h"
|
||||||
|
|
||||||
@@ -1679,7 +1680,7 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
|
|||||||
self_vmas_path,
|
self_vmas_path,
|
||||||
sizeof(task_args->self_vmas_path));
|
sizeof(task_args->self_vmas_path));
|
||||||
|
|
||||||
rst_mutex_init(&task_args->rst_lock);
|
cr_mutex_init(&task_args->rst_lock);
|
||||||
|
|
||||||
strncpy(task_args->ns_last_pid_path,
|
strncpy(task_args->ns_last_pid_path,
|
||||||
LAST_PID_PATH,
|
LAST_PID_PATH,
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
#ifndef ATOMIC_H__
|
#ifndef ATOMIC_H__
|
||||||
#define ATOMIC_H__
|
#define ATOMIC_H__
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
#define atomic_set(mem, v) \
|
#define atomic_set(mem, v) \
|
||||||
({ \
|
({ \
|
||||||
asm volatile ("lock xchg %0, %1\n" \
|
asm volatile ("lock xchg %0, %1\n" \
|
||||||
|
107
include/lock.h
Normal file
107
include/lock.h
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#ifndef CR_LOCK_H_
|
||||||
|
#define CR_LOCK_H_
|
||||||
|
|
||||||
|
#include <linux/futex.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "atomic.h"
|
||||||
|
#include "syscall.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set futex @v value to @val and wake up all waiters
|
||||||
|
*/
|
||||||
|
static always_inline void cr_wait_set(u32 *v, u32 val)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
atomic_set(v, val);
|
||||||
|
|
||||||
|
ret = sys_futex(v, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
|
||||||
|
BUG_ON(ret < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrement futex @v value to @val and wake up all waiters
|
||||||
|
*/
|
||||||
|
static always_inline void cr_wait_dec(u32 *v)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
atomic_dec(v);
|
||||||
|
|
||||||
|
ret = sys_futex(v, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
|
||||||
|
BUG_ON(ret < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait until futex @v value become @val
|
||||||
|
*/
|
||||||
|
static always_inline void cr_wait_until(u32 *v, u32 val)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
tmp = *v;
|
||||||
|
if (tmp == val)
|
||||||
|
break;
|
||||||
|
ret = sys_futex(v, FUTEX_WAIT, tmp, NULL, NULL, 0);
|
||||||
|
BUG_ON(ret < 0 && ret != -EWOULDBLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait while futex @v value is @val
|
||||||
|
*/
|
||||||
|
static always_inline void cr_wait_while(u32 *v, u32 val)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while (*v == val) {
|
||||||
|
ret = sys_futex(v, FUTEX_WAIT, val, NULL, NULL, 0);
|
||||||
|
BUG_ON(ret < 0 && ret != -EWOULDBLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init @mutex value
|
||||||
|
*/
|
||||||
|
static void always_inline cr_mutex_init(u32 *mutex)
|
||||||
|
{
|
||||||
|
u32 c = 0;
|
||||||
|
atomic_set(mutex, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock @mutex
|
||||||
|
*/
|
||||||
|
static void always_inline cr_mutex_lock(u32 *mutex)
|
||||||
|
{
|
||||||
|
u32 c;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while ((c = atomic_inc(mutex))) {
|
||||||
|
ret = sys_futex(mutex, FUTEX_WAIT, c + 1, NULL, NULL, 0);
|
||||||
|
BUG_ON(ret < 0 && ret != -EWOULDBLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unlock @mutex
|
||||||
|
*/
|
||||||
|
static void always_inline cr_mutex_unlock(u32 *mutex)
|
||||||
|
{
|
||||||
|
u32 c = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
atomic_set(mutex, c);
|
||||||
|
|
||||||
|
ret = sys_futex(mutex, FUTEX_WAKE, 1, NULL, NULL, 0);
|
||||||
|
BUG_ON(ret < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CR_LOCK_H_ */
|
@@ -7,6 +7,7 @@
|
|||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "lock.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#ifndef CONFIG_X86_64
|
#ifndef CONFIG_X86_64
|
||||||
@@ -49,15 +50,13 @@ struct restore_mem_zone {
|
|||||||
#define first_on_heap(ptr, heap) ((typeof(ptr))heap)
|
#define first_on_heap(ptr, heap) ((typeof(ptr))heap)
|
||||||
#define next_on_heap(ptr, prev) ((typeof(ptr))((long)(prev) + sizeof(*(prev))))
|
#define next_on_heap(ptr, prev) ((typeof(ptr))((long)(prev) + sizeof(*(prev))))
|
||||||
|
|
||||||
typedef u32 rst_mutex_t;
|
|
||||||
|
|
||||||
/* Make sure it's pow2 in size */
|
/* Make sure it's pow2 in size */
|
||||||
struct thread_restore_args {
|
struct thread_restore_args {
|
||||||
struct restore_mem_zone mem_zone;
|
struct restore_mem_zone mem_zone;
|
||||||
|
|
||||||
int pid;
|
int pid;
|
||||||
int fd_core;
|
int fd_core;
|
||||||
rst_mutex_t *rst_lock;
|
u32 *rst_lock;
|
||||||
} __aligned(sizeof(long));
|
} __aligned(sizeof(long));
|
||||||
|
|
||||||
struct task_restore_core_args {
|
struct task_restore_core_args {
|
||||||
@@ -72,7 +71,7 @@ struct task_restore_core_args {
|
|||||||
};
|
};
|
||||||
char ns_last_pid_path[PATH_MAX];
|
char ns_last_pid_path[PATH_MAX];
|
||||||
bool restore_threads; /* if to restore threads */
|
bool restore_threads; /* if to restore threads */
|
||||||
rst_mutex_t rst_lock;
|
u32 rst_lock;
|
||||||
|
|
||||||
/* threads restoration */
|
/* threads restoration */
|
||||||
int nr_threads; /* number of threads */
|
int nr_threads; /* number of threads */
|
||||||
@@ -288,29 +287,6 @@ static void always_inline write_hex_n(unsigned long num)
|
|||||||
sys_write(STDERR_FILENO, &c, 1);
|
sys_write(STDERR_FILENO, &c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FUTEX_WAIT 0
|
|
||||||
#define FUTEX_WAKE 1
|
|
||||||
|
|
||||||
static void always_inline rst_mutex_init(rst_mutex_t *mutex)
|
|
||||||
{
|
|
||||||
u32 c = 0;
|
|
||||||
atomic_set(mutex, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void always_inline rst_mutex_lock(rst_mutex_t *mutex)
|
|
||||||
{
|
|
||||||
u32 c;
|
|
||||||
while ((c = atomic_inc(mutex)))
|
|
||||||
sys_futex(mutex, FUTEX_WAIT, c + 1, NULL, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void always_inline rst_mutex_unlock(rst_mutex_t *mutex)
|
|
||||||
{
|
|
||||||
u32 c = 0;
|
|
||||||
atomic_set(mutex, c);
|
|
||||||
sys_futex(mutex, FUTEX_WAKE, 1, NULL, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need own handler */
|
/* We need own handler */
|
||||||
|
|
||||||
#ifdef BUG_ON_HANDLER
|
#ifdef BUG_ON_HANDLER
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
|
||||||
#include "crtools.h"
|
#include "crtools.h"
|
||||||
|
#include "lock.h"
|
||||||
#include "restorer.h"
|
#include "restorer.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -95,7 +96,7 @@ long restore_thread(long cmd, struct thread_restore_args *args)
|
|||||||
goto core_restore_end;
|
goto core_restore_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
rst_mutex_unlock(args->rst_lock);
|
cr_mutex_unlock(args->rst_lock);
|
||||||
|
|
||||||
new_sp = (long)rt_sigframe + 8;
|
new_sp = (long)rt_sigframe + 8;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
@@ -454,7 +455,7 @@ self_len_end:
|
|||||||
if (thread_args[i].pid == args->pid)
|
if (thread_args[i].pid == args->pid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rst_mutex_lock(&args->rst_lock);
|
cr_mutex_lock(&args->rst_lock);
|
||||||
|
|
||||||
new_sp =
|
new_sp =
|
||||||
RESTORE_ALIGN_STACK((long)thread_args[i].mem_zone.stack,
|
RESTORE_ALIGN_STACK((long)thread_args[i].mem_zone.stack,
|
||||||
|
Reference in New Issue
Block a user