drm/via: set FOLL_PIN via pin_user_pages_fast()
[linux-2.6-microblaze.git] / mm / zswap.c
index 0e22744..46a3223 100644 (file)
@@ -856,7 +856,6 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
        /* extract swpentry from data */
        zhdr = zpool_map_handle(pool, handle, ZPOOL_MM_RO);
        swpentry = zhdr->swpentry; /* here */
-       zpool_unmap_handle(pool, handle);
        tree = zswap_trees[swp_type(swpentry)];
        offset = swp_offset(swpentry);
 
@@ -866,6 +865,7 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
        if (!entry) {
                /* entry was invalidated */
                spin_unlock(&tree->lock);
+               zpool_unmap_handle(pool, handle);
                return 0;
        }
        spin_unlock(&tree->lock);
@@ -886,15 +886,13 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
        case ZSWAP_SWAPCACHE_NEW: /* page is locked */
                /* decompress */
                dlen = PAGE_SIZE;
-               src = (u8 *)zpool_map_handle(entry->pool->zpool, entry->handle,
-                               ZPOOL_MM_RO) + sizeof(struct zswap_header);
+               src = (u8 *)zhdr + sizeof(struct zswap_header);
                dst = kmap_atomic(page);
                tfm = *get_cpu_ptr(entry->pool->tfm);
                ret = crypto_comp_decompress(tfm, src, entry->length,
                                             dst, &dlen);
                put_cpu_ptr(entry->pool->tfm);
                kunmap_atomic(dst);
-               zpool_unmap_handle(entry->pool->zpool, entry->handle);
                BUG_ON(ret);
                BUG_ON(dlen != PAGE_SIZE);
 
@@ -940,6 +938,7 @@ fail:
        spin_unlock(&tree->lock);
 
 end:
+       zpool_unmap_handle(pool, handle);
        return ret;
 }
 
@@ -997,6 +996,7 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
        char *buf;
        u8 *src, *dst;
        struct zswap_header zhdr = { .swpentry = swp_entry(type, offset) };
+       gfp_t gfp;
 
        /* THP isn't supported */
        if (PageTransHuge(page)) {
@@ -1070,9 +1070,10 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
 
        /* store */
        hlen = zpool_evictable(entry->pool->zpool) ? sizeof(zhdr) : 0;
-       ret = zpool_malloc(entry->pool->zpool, hlen + dlen,
-                          __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM,
-                          &handle);
+       gfp = __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM;
+       if (zpool_malloc_support_movable(entry->pool->zpool))
+               gfp |= __GFP_HIGHMEM | __GFP_MOVABLE;
+       ret = zpool_malloc(entry->pool->zpool, hlen + dlen, gfp, &handle);
        if (ret == -ENOSPC) {
                zswap_reject_compress_poor++;
                goto put_dstmem;