@@ -1080,7 +1080,17 @@ static void zswap_decompress(struct zswap_entry *entry, struct page *page)
1080
1080
mutex_lock (& acomp_ctx -> mutex );
1081
1081
1082
1082
src = zpool_map_handle (zpool , entry -> handle , ZPOOL_MM_RO );
1083
- if (acomp_ctx -> is_sleepable && !zpool_can_sleep_mapped (zpool )) {
1083
+ /*
1084
+ * If zpool_map_handle is atomic, we cannot reliably utilize its mapped buffer
1085
+ * to do crypto_acomp_decompress() which might sleep. In such cases, we must
1086
+ * resort to copying the buffer to a temporary one.
1087
+ * Meanwhile, zpool_map_handle() might return a non-linearly mapped buffer,
1088
+ * such as a kmap address of high memory or even ever a vmap address.
1089
+ * However, sg_init_one is only equipped to handle linearly mapped low memory.
1090
+ * In such cases, we also must copy the buffer to a temporary and lowmem one.
1091
+ */
1092
+ if ((acomp_ctx -> is_sleepable && !zpool_can_sleep_mapped (zpool )) ||
1093
+ !virt_addr_valid (src )) {
1084
1094
memcpy (acomp_ctx -> buffer , src , entry -> length );
1085
1095
src = acomp_ctx -> buffer ;
1086
1096
zpool_unmap_handle (zpool , entry -> handle );
@@ -1094,7 +1104,7 @@ static void zswap_decompress(struct zswap_entry *entry, struct page *page)
1094
1104
BUG_ON (acomp_ctx -> req -> dlen != PAGE_SIZE );
1095
1105
mutex_unlock (& acomp_ctx -> mutex );
1096
1106
1097
- if (! acomp_ctx -> is_sleepable || zpool_can_sleep_mapped ( zpool ) )
1107
+ if (src != acomp_ctx -> buffer )
1098
1108
zpool_unmap_handle (zpool , entry -> handle );
1099
1109
}
1100
1110
0 commit comments