return *(unsigned long *)handle;
}
-static unsigned long obj_to_head(struct page *page, void *obj)
+static bool obj_allocated(struct page *page, void *obj, unsigned long *phandle)
{
+ unsigned long handle;
+
if (unlikely(PageHugeObject(page))) {
VM_BUG_ON_PAGE(!is_first_page(page), page);
- return page->index;
+ handle = page->index;
} else
- return *(unsigned long *)obj;
+ handle = *(unsigned long *)obj;
+
+ if (!(handle & OBJ_ALLOCATED_TAG))
+ return false;
+
+ *phandle = handle & ~OBJ_ALLOCATED_TAG;
+ return true;
}
static inline int testpin_tag(unsigned long handle)
static unsigned long find_alloced_obj(struct size_class *class,
struct page *page, int *obj_idx)
{
- unsigned long head;
int offset = 0;
int index = *obj_idx;
unsigned long handle = 0;
offset += class->size * index;
while (offset < PAGE_SIZE) {
- head = obj_to_head(page, addr + offset);
- if (head & OBJ_ALLOCATED_TAG) {
- handle = head & ~OBJ_ALLOCATED_TAG;
+ if (obj_allocated(page, addr + offset, &handle)) {
if (trypin_tag(handle))
break;
handle = 0;
struct page *dummy;
void *s_addr, *d_addr, *addr;
int offset, pos;
- unsigned long handle, head;
+ unsigned long handle;
unsigned long old_obj, new_obj;
unsigned int obj_idx;
int ret = -EAGAIN;
pos = offset;
s_addr = kmap_atomic(page);
while (pos < PAGE_SIZE) {
- head = obj_to_head(page, s_addr + pos);
- if (head & OBJ_ALLOCATED_TAG) {
- handle = head & ~OBJ_ALLOCATED_TAG;
+ if (obj_allocated(page, s_addr + pos, &handle)) {
if (!trypin_tag(handle))
goto unpin_objects;
}
for (addr = s_addr + offset; addr < s_addr + pos;
addr += class->size) {
- head = obj_to_head(page, addr);
- if (head & OBJ_ALLOCATED_TAG) {
- handle = head & ~OBJ_ALLOCATED_TAG;
+ if (obj_allocated(page, addr, &handle)) {
BUG_ON(!testpin_tag(handle));
old_obj = handle_to_obj(handle);
unpin_objects:
for (addr = s_addr + offset; addr < s_addr + pos;
addr += class->size) {
- head = obj_to_head(page, addr);
- if (head & OBJ_ALLOCATED_TAG) {
- handle = head & ~OBJ_ALLOCATED_TAG;
+ if (obj_allocated(page, addr, &handle)) {
BUG_ON(!testpin_tag(handle));
unpin_tag(handle);
}