[CRIU] [PATCH 04/24] parasite: Use thread state hash for fast lookup over thread state areas
Andrey Vagin
avagin at openvz.org
Wed May 22 16:08:05 EDT 2013
From: Cyrill Gorcunov <gorcunov at openvz.org>
We lookup for threads state via hash map, which makes fini
sequence to provide @real for parasite code.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
include/parasite.h | 1 +
parasite-syscall.c | 17 ++++++++++++++++-
pie/parasite.c | 46 ++++++++++++++++++++++++++++------------------
3 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/include/parasite.h b/include/parasite.h
index 2c4965b..ba9da39 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -115,6 +115,7 @@ struct parasite_dump_creds {
struct parasite_dump_thread {
unsigned int *tid_addr;
+ pid_t real;
pid_t tid;
k_rtsigset_t blocked;
u32 tls;
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 68caf32..744b1d4 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -362,6 +362,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, struct pid *tid,
int ret;
args = parasite_args(ctl, struct parasite_dump_thread);
+ args->real = tid->real;
ret = parasite_execute_trap_by_pid(PARASITE_CMD_DUMP_THREAD, ctl, tid->real);
@@ -557,12 +558,16 @@ int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *i
int parasite_fini_threads_seized(struct parasite_ctl *ctl, struct pstree_item *item)
{
+ struct parasite_init_args *args;
int ret = 0, i;
+ args = parasite_args(ctl, struct parasite_init_args);
+
for (i = 0; i < item->nr_threads; i++) {
if (item->pid.real == item->threads[i].real)
continue;
+ args->real = item->threads[i].real;
ret = parasite_execute_trap_by_pid(PARASITE_CMD_FINI_THREAD, ctl,
item->threads[i].real);
/*
@@ -587,6 +592,16 @@ int parasite_fini_threads_seized(struct parasite_ctl *ctl, struct pstree_item *i
return ret;
}
+static int parasite_fini_seized(struct parasite_ctl *ctl)
+{
+ struct parasite_init_args *args;
+
+ args = parasite_args(ctl, struct parasite_init_args);
+ args->real = ctl->pid.real;
+
+ return parasite_execute_trap(PARASITE_CMD_FINI, ctl);
+}
+
int parasite_cure_remote(struct parasite_ctl *ctl, struct pstree_item *item)
{
int ret = 0;
@@ -596,7 +611,7 @@ int parasite_cure_remote(struct parasite_ctl *ctl, struct pstree_item *item)
if (ctl->parasite_ip) {
ctl->signals_blocked = 0;
parasite_fini_threads_seized(ctl, item);
- parasite_execute_trap(PARASITE_CMD_FINI, ctl);
+ parasite_fini_seized(ctl);
}
if (ctl->remote_map) {
diff --git a/pie/parasite.c b/pie/parasite.c
index dcb4a60..28f126d 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -21,6 +21,7 @@ static struct tid_state_s {
pid_t tid;
bool use_sig_blocked;
k_rtsigset_t sig_blocked;
+ void *next;
unsigned char stack[PARASITE_STACK_SIZE] __aligned(8);
} *tid_state;
@@ -36,6 +37,8 @@ static unsigned int next_tid_state;
#define SPLICE_F_GIFT 0x08
#endif
+static struct tid_state_s *tid_table[512];
+
static int mprotect_vmas(struct parasite_dump_pages_args *args)
{
struct parasite_vma_entry *vmas, *vma;
@@ -173,18 +176,23 @@ static int drain_fds(struct parasite_drain_fd *args)
return ret;
}
-static struct tid_state_s *find_thread_state(pid_t tid)
+static void hash_thread_state(struct tid_state_s *s)
+{
+ unsigned int pos = s->real % ARRAY_SIZE(tid_table);
+ struct tid_state_s *next = tid_table[pos];
+
+ tid_table[pos] = s;
+ s->next = next;
+}
+
+static struct tid_state_s *find_thread_state(pid_t real)
{
- unsigned int i;
-
- /*
- * FIXME
- *
- * We need a hash here rather
- */
- for (i = 0; i < next_tid_state; i++) {
- if (tid_state[i].tid == tid)
- return &tid_state[i];
+ unsigned int pos = real % ARRAY_SIZE(tid_table);
+ struct tid_state_s *s;
+
+ for (s = tid_table[pos]; s; s = s->next) {
+ if (s->real == real)
+ return s;
}
return NULL;
@@ -196,7 +204,7 @@ static int dump_thread(struct parasite_dump_thread *args)
struct tid_state_s *s;
int ret;
- s = find_thread_state(tid);
+ s = find_thread_state(args->real);
if (!s)
return -ENOENT;
@@ -231,16 +239,18 @@ static int init_thread(struct parasite_init_args *args)
tid_state[next_tid_state].tid = sys_gettid();
tid_state[next_tid_state].real = args->real;
+ hash_thread_state(&tid_state[next_tid_state]);
+
next_tid_state++;
return ret;
}
-static int fini_thread(void)
+static int fini_thread(struct parasite_init_args *args)
{
struct tid_state_s *s;
- s = find_thread_state(sys_gettid());
+ s = find_thread_state(args->real);
if (!s)
return -ENOENT;
@@ -418,11 +428,11 @@ static int parasite_cfg_log(struct parasite_log_args *args)
return ret;
}
-static int fini(void)
+static int fini(struct parasite_init_args *args)
{
int ret;
- ret = fini_thread();
+ ret = fini_thread(args);
sys_munmap(tid_state, TID_STATE_SIZE(nr_tid_state));
log_set_fd(-1);
@@ -441,9 +451,9 @@ int __used parasite_service(unsigned int cmd, void *args)
case PARASITE_CMD_INIT_THREAD:
return init_thread(args);
case PARASITE_CMD_FINI:
- return fini();
+ return fini(args);
case PARASITE_CMD_FINI_THREAD:
- return fini_thread();
+ return fini_thread(args);
case PARASITE_CMD_CFG_LOG:
return parasite_cfg_log(args);
case PARASITE_CMD_DUMPPAGES:
--
1.8.2
More information about the CRIU
mailing list