staging: zcache: fix crash on high memory swap
zcache_put_page() was modified to pass page_address(page) instead of the actual page structure. In combination with the function signature changes to tmem_put() and zcache_pampd_create(), zcache_pampd_create() tries to (re)derive the page structure from the virtual address. However, if the original page is a high memory page (or any unmapped page), this virt_to_page() fails because the page_address() in zcache_put_page() returned NULL. This patch changes zcache_put_page() and zcache_get_page() to pass the page structure instead of the page's virtual address, which may or may not exist. Signed-off-by: Seth Jennings <sjenning@linux.vnet.ibm.com> Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
20cc7995fe
Коммит
c5f5c4db39
|
@ -1158,7 +1158,7 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph,
|
|||
size_t clen;
|
||||
int ret;
|
||||
unsigned long count;
|
||||
struct page *page = virt_to_page(data);
|
||||
struct page *page = (struct page *)(data);
|
||||
struct zcache_client *cli = pool->client;
|
||||
uint16_t client_id = get_client_id_from_client(cli);
|
||||
unsigned long zv_mean_zsize;
|
||||
|
@ -1227,7 +1227,7 @@ static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw,
|
|||
int ret = 0;
|
||||
|
||||
BUG_ON(is_ephemeral(pool));
|
||||
zv_decompress(virt_to_page(data), pampd);
|
||||
zv_decompress((struct page *)(data), pampd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1539,7 +1539,7 @@ static int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp,
|
|||
goto out;
|
||||
if (!zcache_freeze && zcache_do_preload(pool) == 0) {
|
||||
/* preload does preempt_disable on success */
|
||||
ret = tmem_put(pool, oidp, index, page_address(page),
|
||||
ret = tmem_put(pool, oidp, index, (char *)(page),
|
||||
PAGE_SIZE, 0, is_ephemeral(pool));
|
||||
if (ret < 0) {
|
||||
if (is_ephemeral(pool))
|
||||
|
@ -1572,7 +1572,7 @@ static int zcache_get_page(int cli_id, int pool_id, struct tmem_oid *oidp,
|
|||
pool = zcache_get_pool_by_id(cli_id, pool_id);
|
||||
if (likely(pool != NULL)) {
|
||||
if (atomic_read(&pool->obj_count) > 0)
|
||||
ret = tmem_get(pool, oidp, index, page_address(page),
|
||||
ret = tmem_get(pool, oidp, index, (char *)(page),
|
||||
&size, 0, is_ephemeral(pool));
|
||||
zcache_put_pool(pool);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче