From 7a16734ed5a22f5ab6333a3c2058d031b315bbde Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 29 Aug 2013 08:07:15 +0400 Subject: [PATCH] rst: Formalize the shared resource restore order Signed-off-by: Pavel Emelyanov --- files.c | 7 +++---- include/crtools.h | 10 ++++++++++ include/files.h | 4 +++- shmem.c | 2 +- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/files.c b/files.c index d8085eea3..2bffcbae7 100644 --- a/files.c +++ b/files.c @@ -443,10 +443,9 @@ static int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info) return -1; } - list_for_each_entry(le, &fdesc->fd_info_head, desc_list) { - if (le->pid > new_le->pid) + list_for_each_entry(le, &fdesc->fd_info_head, desc_list) + if (pid_rst_prio(new_le->pid, le->pid)) break; - } list_add_tail(&new_le->desc_list, &le->desc_list); new_le->desc = fdesc; @@ -972,7 +971,7 @@ int shared_fdt_prepare(struct pstree_item *item) item->rst->fdt = fdt; item->rst->service_fd_id = fdt->nr; fdt->nr++; - if (fdt->pid > item->pid.virt) + if (pid_rst_prio(item->pid.virt, fdt->pid)) fdt->pid = item->pid.virt; return 0; diff --git a/include/crtools.h b/include/crtools.h index 7319992b3..3c90b2994 100644 --- a/include/crtools.h +++ b/include/crtools.h @@ -189,4 +189,14 @@ static inline int in_vma_area(struct vma_area *vma, unsigned long addr) addr < (unsigned long)vma->vma.end; } +/* + * When we have to restore a shared resource, we mush select which + * task should do it, and make other(s) wait for it. In order to + * avoid deadlocks, always make task with lower pid be the restorer. + */ +static inline bool pid_rst_prio(unsigned pid_a, unsigned pid_b) +{ + return pid_a < pid_b; +} + #endif /* __CR_CRTOOLS_H__ */ diff --git a/include/files.h b/include/files.h index 2e3ac14e2..1d195b749 100644 --- a/include/files.h +++ b/include/files.h @@ -6,6 +6,7 @@ #include "lock.h" #include "list.h" #include "image.h" +#include "crtools.h" #include "protobuf/fdinfo.pb-c.h" #include "protobuf/fown.pb-c.h" @@ -69,7 +70,8 @@ struct fdinfo_list_entry { /* reports whether fd_a takes prio over fd_b */ static inline int fdinfo_rst_prio(struct fdinfo_list_entry *fd_a, struct fdinfo_list_entry *fd_b) { - return (fd_a->pid < fd_b->pid) || ((fd_a->pid == fd_b->pid) && (fd_a->fe->fd < fd_b->fe->fd)); + return pid_rst_prio(fd_a->pid, fd_b->pid) || + ((fd_a->pid == fd_b->pid) && (fd_a->fe->fd < fd_b->fe->fd)); } struct file_desc_ops { diff --git a/shmem.c b/shmem.c index 529e2f430..769dc3007 100644 --- a/shmem.c +++ b/shmem.c @@ -44,7 +44,7 @@ static int collect_shmem(int pid, VmaEntry *vi) * will wait until the kernel propagate this mapping * into /proc */ - if (si->pid <= pid) + if (!pid_rst_prio(pid, si->pid)) return 0; si->pid = pid;