mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-21 05:27:52 +07:00
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:
parent
20cc7995fe
commit
c5f5c4db39
@ -1158,7 +1158,7 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph,
|
|||||||
size_t clen;
|
size_t clen;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
struct page *page = virt_to_page(data);
|
struct page *page = (struct page *)(data);
|
||||||
struct zcache_client *cli = pool->client;
|
struct zcache_client *cli = pool->client;
|
||||||
uint16_t client_id = get_client_id_from_client(cli);
|
uint16_t client_id = get_client_id_from_client(cli);
|
||||||
unsigned long zv_mean_zsize;
|
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;
|
int ret = 0;
|
||||||
|
|
||||||
BUG_ON(is_ephemeral(pool));
|
BUG_ON(is_ephemeral(pool));
|
||||||
zv_decompress(virt_to_page(data), pampd);
|
zv_decompress((struct page *)(data), pampd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1539,7 +1539,7 @@ static int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp,
|
|||||||
goto out;
|
goto out;
|
||||||
if (!zcache_freeze && zcache_do_preload(pool) == 0) {
|
if (!zcache_freeze && zcache_do_preload(pool) == 0) {
|
||||||
/* preload does preempt_disable on success */
|
/* 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));
|
PAGE_SIZE, 0, is_ephemeral(pool));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (is_ephemeral(pool))
|
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);
|
pool = zcache_get_pool_by_id(cli_id, pool_id);
|
||||||
if (likely(pool != NULL)) {
|
if (likely(pool != NULL)) {
|
||||||
if (atomic_read(&pool->obj_count) > 0)
|
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));
|
&size, 0, is_ephemeral(pool));
|
||||||
zcache_put_pool(pool);
|
zcache_put_pool(pool);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user