|
@@ -284,6 +284,7 @@ static DEFINE_MUTEX(swap_cgroup_mutex);
|
|
struct swap_cgroup_ctrl {
|
|
struct swap_cgroup_ctrl {
|
|
struct page **map;
|
|
struct page **map;
|
|
unsigned long length;
|
|
unsigned long length;
|
|
|
|
+ spinlock_t lock;
|
|
};
|
|
};
|
|
|
|
|
|
struct swap_cgroup_ctrl swap_cgroup_ctrl[MAX_SWAPFILES];
|
|
struct swap_cgroup_ctrl swap_cgroup_ctrl[MAX_SWAPFILES];
|
|
@@ -353,16 +354,22 @@ unsigned short swap_cgroup_cmpxchg(swp_entry_t ent,
|
|
struct swap_cgroup_ctrl *ctrl;
|
|
struct swap_cgroup_ctrl *ctrl;
|
|
struct page *mappage;
|
|
struct page *mappage;
|
|
struct swap_cgroup *sc;
|
|
struct swap_cgroup *sc;
|
|
|
|
+ unsigned long flags;
|
|
|
|
+ unsigned short retval;
|
|
|
|
|
|
ctrl = &swap_cgroup_ctrl[type];
|
|
ctrl = &swap_cgroup_ctrl[type];
|
|
|
|
|
|
mappage = ctrl->map[idx];
|
|
mappage = ctrl->map[idx];
|
|
sc = page_address(mappage);
|
|
sc = page_address(mappage);
|
|
sc += pos;
|
|
sc += pos;
|
|
- if (cmpxchg(&sc->id, old, new) == old)
|
|
|
|
- return old;
|
|
|
|
|
|
+ spin_lock_irqsave(&ctrl->lock, flags);
|
|
|
|
+ retval = sc->id;
|
|
|
|
+ if (retval == old)
|
|
|
|
+ sc->id = new;
|
|
else
|
|
else
|
|
- return 0;
|
|
|
|
|
|
+ retval = 0;
|
|
|
|
+ spin_unlock_irqrestore(&ctrl->lock, flags);
|
|
|
|
+ return retval;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -383,13 +390,17 @@ unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id)
|
|
struct page *mappage;
|
|
struct page *mappage;
|
|
struct swap_cgroup *sc;
|
|
struct swap_cgroup *sc;
|
|
unsigned short old;
|
|
unsigned short old;
|
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
ctrl = &swap_cgroup_ctrl[type];
|
|
ctrl = &swap_cgroup_ctrl[type];
|
|
|
|
|
|
mappage = ctrl->map[idx];
|
|
mappage = ctrl->map[idx];
|
|
sc = page_address(mappage);
|
|
sc = page_address(mappage);
|
|
sc += pos;
|
|
sc += pos;
|
|
- old = xchg(&sc->id, id);
|
|
|
|
|
|
+ spin_lock_irqsave(&ctrl->lock, flags);
|
|
|
|
+ old = sc->id;
|
|
|
|
+ sc->id = id;
|
|
|
|
+ spin_unlock_irqrestore(&ctrl->lock, flags);
|
|
|
|
|
|
return old;
|
|
return old;
|
|
}
|
|
}
|
|
@@ -441,6 +452,7 @@ int swap_cgroup_swapon(int type, unsigned long max_pages)
|
|
mutex_lock(&swap_cgroup_mutex);
|
|
mutex_lock(&swap_cgroup_mutex);
|
|
ctrl->length = length;
|
|
ctrl->length = length;
|
|
ctrl->map = array;
|
|
ctrl->map = array;
|
|
|
|
+ spin_lock_init(&ctrl->lock);
|
|
if (swap_cgroup_prepare(type)) {
|
|
if (swap_cgroup_prepare(type)) {
|
|
/* memory shortage */
|
|
/* memory shortage */
|
|
ctrl->map = NULL;
|
|
ctrl->map = NULL;
|