为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

内核编译和嵌入式产品的设计与开发
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#1

帖子 科学之子 » 2016-03-16 21:19

为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?
难道是为了兼容现有swap空间的数据格式吗?

代码: 全选

//代码所在文件
//zswap.c:
//代码所在函数
//static int zswap_writeback_entry(struct zpool *pool, unsigned long handle):

		/* decompress */
		dlen = PAGE_SIZE;
		src = (u8 *)zpool_map_handle(entry->pool->zpool, entry->handle,
				ZPOOL_MM_RO) + 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);

		/* page is up to date */
		SetPageUptodate(page);
	}

	/* move it to the tail of the inactive list after end_writeback */
	SetPageReclaim(page);

	/* start writeback */
	__swap_writepage(page, &wbc, end_swap_bio_write);
	page_cache_release(page);
	zswap_written_back_pages++;
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#3

帖子 科学之子 » 2016-03-29 18:25

突然YY到一种可能性...
就是swap space这种东西必然只有两种数据结构,顺序偏移或树
已压缩的数据无法直接通过偏移寻址.
所以如果swap space存储的是已压缩数据,就必然需要通过树之类的结构来索引寻址,结果就是在低速设备上进行类似树查找之类的操作;
效率下降可想而知,机械硬盘之类不擅长随机读写的设备更甚.

所以zswap通过解压后再swap out的方式来允许在低速设备上直接通过字节偏移寻址.

:em06 不知是否正确,欢迎各位指正
poloshiao
论坛版主
帖子: 18279
注册时间: 2009-08-04 16:33

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#4

帖子 poloshiao » 2016-03-29 18:33

https://en.wikipedia.org/wiki/Zswap
zswap is a Linux kernel feature that provides a compressed write-back cache for swapped pages, as a form of virtual memory compression.
zswap performs their compression and then stores them into a memory pool dynamically allocated in the system RAM.

https://zh.wikipedia.org/wiki/Zswap
zswap是一项Linux内核的虚拟内存压缩功能,可为将要交换的页面提供压缩回写缓存。
zswap不将其移动到交换设备,而是对其执行压缩,然后存储到系统RAM内动态分配的内存池中。
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#5

帖子 科学之子 » 2016-03-29 20:00

poloshiao 写了:https://en.wikipedia.org/wiki/Zswap
zswap is a Linux kernel feature that provides a compressed write-back cache for swapped pages, as a form of virtual memory compression.
zswap performs their compression and then stores them into a memory pool dynamically allocated in the system RAM.

https://zh.wikipedia.org/wiki/Zswap
zswap是一项Linux内核的虚拟内存压缩功能,可为将要交换的页面提供压缩回写缓存。
zswap不将其移动到交换设备,而是对其执行压缩,然后存储到系统RAM内动态分配的内存池中。
这些介绍虽然也是zswap,但只是概念性的介绍.
http://kernel.taobao.org/index.php?titl ... arch&ns0=1
更深入的介绍zswap的具体实现相关信息
我目前的理解是zswap的压缩缓存只是让等量的内存可以缓存更多页面
但是在缓存命中失败,实际swap out/in发生时却无法降低IO带宽

zswap这么做的确切原因我还不了解,出于我3楼的描述,还是单纯的为了兼容现有swap space的数据结构?亦或是单纯为了实现简单?
头像
astolia
论坛版主
帖子: 6436
注册时间: 2008-09-18 13:11

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#6

帖子 astolia » 2016-04-25 11:01

这也能有问题?swap里面本来就是放的未压缩页数据,你现在扔个压缩了的进去是什么意思?
看起来你对整个流程还不清楚,你上面贴出来的zswap_writeback_entry()前面的注释也没去看
/*
* Attempts to free an entry by adding a page to the swap cache,
* decompressing the entry data into the page, and issuing a
* bio write to write the page back to the swap device.
*
* This can be thought of as a "resumed writeback" of the page
* to the swap device. We are basically resuming the same swap
* writeback path that was intercepted with the frontswap_store()
* in the first place. After the page has been decompressed into
* the swap cache, the compressed version stored by zswap can be
* freed.

*/
注意看红字部分。zswap的writeback的目的就是为了在zpool中腾出空间,所以回写后,原有的压缩页会从zpool中移除。也就是zswap(暂时)不再去负责那块内存页了,当然就不能想当然地把压缩后的数据放到swap里
我目前的理解是zswap的压缩缓存只是让等量的内存可以缓存更多页面
但是在缓存命中失败,实际swap out/in发生时却无法降低IO带宽
IO带宽是个什么东西?我猜你指的是IO次数或数据量。可以做个思想实验。
假设:有总共100个内存页。拿出50个页的空间做zswap,压缩率是50%,zpool总共能放100个页的数据。现有进程共占用150个页,其中50个页已经在swap。无zswap时100页在内存,有zswap时50个页在普通内存,50个页在zpool。
从swap中移50个页回内存:无zswap时,先移50个页出去,再移50个页回来。有zswap时,50个页从普通内存移到zpool,zpool被填满,再从swap移50个页到内存。IO比为100:50
新来了50个页:无zswap时,需要再移50个页出去。有zswap时,需要从zpool中提出50个页扔swap。IO比为50:50
从swap中移50个页回内存:无zswap时,先移50个页出去,再移50个页回来。有zswap时,从zpool中移50个页到swap,原内存中50个页进zswap,swap中移50个页回内存。IO比为100:100
从上面可以看出,只有在极端情况即zpool被填满时,才会导致有无zswap的IO情况相同。只要zpool还有空闲空间,就能减少IO数量
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#7

帖子 科学之子 » 2016-04-26 19:30

astolia 写了:这也能有问题?swap里面本来就是放的未压缩页数据,你现在扔个压缩了的进去是什么意思?
看起来你对整个流程还不清楚,你上面贴出来的zswap_writeback_entry()前面的注释也没去看
/*
* Attempts to free an entry by adding a page to the swap cache,
* decompressing the entry data into the page, and issuing a
* bio write to write the page back to the swap device.
*
* This can be thought of as a "resumed writeback" of the page
* to the swap device. We are basically resuming the same swap
* writeback path that was intercepted with the frontswap_store()
* in the first place. After the page has been decompressed into
* the swap cache, the compressed version stored by zswap can be
* freed.

*/
注意看红字部分。zswap的writeback的目的就是为了在zpool中腾出空间,所以回写后,原有的压缩页会从zpool中移除。也就是zswap(暂时)不再去负责那块内存页了,当然就不能想当然地把压缩后的数据放到swap里
我目前的理解是zswap的压缩缓存只是让等量的内存可以缓存更多页面
但是在缓存命中失败,实际swap out/in发生时却无法降低IO带宽
IO带宽是个什么东西?我猜你指的是IO次数或数据量。可以做个思想实验。
假设:有总共100个内存页。拿出50个页的空间做zswap,压缩率是50%,zpool总共能放100个页的数据。现有进程共占用150个页,其中50个页已经在swap。无zswap时100页在内存,有zswap时50个页在普通内存,50个页在zpool。
从swap中移50个页回内存:无zswap时,先移50个页出去,再移50个页回来。有zswap时,50个页从普通内存移到zpool,zpool被填满,再从swap移50个页到内存。IO比为100:50
新来了50个页:无zswap时,需要再移50个页出去。有zswap时,需要从zpool中提出50个页扔swap。IO比为50:50
从swap中移50个页回内存:无zswap时,先移50个页出去,再移50个页回来。有zswap时,从zpool中移50个页到swap,原内存中50个页进zswap,swap中移50个页回内存。IO比为100:100
从上面可以看出,只有在极端情况即zpool被填满时,才会导致有无zswap的IO情况相同。只要zpool还有空闲空间,就能减少IO数量
1:之所以提出这个问题,好像是当时搜索结果显示zfs无法支持swap
https://wiki.archlinux.org/index.php/ZFS#Swap_volume
It is importart to set the ZVOL block size to match the system page size
需要貌似需要设置定长数据块,但压缩需要变长数据块

2:存储设备启用压缩的话IO吞吐量会更快:
http://blog.csdn.net/dong976209075/arti ... ls/7906687
3:貌似zfs的swap设备支持压缩?:
http://www.oschina.net/translate/runnin ... nabled-zfs
迷茫了.

swap里面本来就是放的未压缩页数据,你现在扔个压缩了的进去是什么意思?
我的理解是如果磁盘中的数据是压缩的,这样swap out时可以避免解压,swap in时读入的数据量也会较小,这意味着磁盘的硬件缓存命中率可能更高;
情况类似2中的链接.
rosynirvana
帖子: 893
注册时间: 2011-02-14 17:46

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#8

帖子 rosynirvana » 2016-04-26 21:43

https://lwn.net/Articles/591961/
都是这么想的啊
从2013年到2014一直有人在问为什么zswap不把压缩后的页写到备用Swap设备上

不过在我看来,是因为无法保证压缩后一个页面会变小,如果压缩后的一个页面变大了,那就没地方放了(接口限制了备用swapping设备只会有一页的空间)
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#9

帖子 科学之子 » 2016-04-27 2:31

rosynirvana 写了:https://lwn.net/Articles/591961/
都是这么想的啊
从2013年到2014一直有人在问为什么zswap不把压缩后的页写到备用Swap设备上

不过在我看来,是因为无法保证压缩后一个页面会变小,如果压缩后的一个页面变大了,那就没地方放了(接口限制了备用swapping设备只会有一页的空间)
"备用swap设备"是什么意思?指的是缓冲区?

如果压缩后页面变大了,那应该立即抛弃压缩结果,用原始数据啊,不然存在zpool里面也是浪费额外空间

zram有个参数,如果压缩效果过低,就会放弃压缩结果,直接存储原始数据
头像
kashu
帖子: 451
注册时间: 2014-02-07 17:31
系统: Xubuntu 14.04.5 64位

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#10

帖子 kashu » 2016-04-27 5:31

科学之子 写了:"备用swap设备"是什么意思?
应该是指操作系统使用的swap分区或swap块设备吧

rosynirvana 写了:如果压缩后的一个页面变大了
使用压缩算法压缩之后Page frame反而会变大,能举几个例子吗?什么情况下反而会变大?


OS: Xubuntu 14.04.5 LTS 64-bit
CPU: Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
RAM: 12GB DDR3 1333MHz
128GB SSD + 2TB HDD
神舟优雅A480B-I5B 购于 2012.08

YouTube频道:https://www.youtube.com/channel/UCGSPXZ ... DuDYX8L6Qg
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#11

帖子 科学之子 » 2016-04-27 6:48

kashu 写了:
科学之子 写了:"备用swap设备"是什么意思?
应该是指操作系统使用的swap分区或swap块设备吧

rosynirvana 写了:如果压缩后的一个页面变大了
使用压缩算法压缩之后Page frame反而会变大,能举几个例子吗?什么情况下反而会变大?
kashu 写了:
科学之子 写了:"备用swap设备"是什么意思?
应该是指操作系统使用的swap分区或swap块设备吧
但我还是不明白,怎么会"只有一个页的大小",听说去不像是"后端"更像是"缓冲区"
rosynirvana 写了:如果压缩后的一个页面变大了
使用压缩算法压缩之后Page frame反而会变大,能举几个例子吗?什么情况下反而会变大?
情况或例子我也不清楚
但是:
http://baike.baidu.com/view/5767680.htm
当处理不可压缩数据的时候,LZO 将每个 1024 字节的输入数据块扩展 16 字节。

另外,不是page frame变大,而是压缩算法在某些情况下的输出结果长度比原始数据长
具体"某些情况"我就不清楚了,我甚至不了解LZO的实现原理
上次由 科学之子 在 2016-04-27 7:05,总共编辑 2 次。
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#12

帖子 科学之子 » 2016-04-27 7:02

kashu 写了:
科学之子 写了:"备用swap设备"是什么意思?
应该是指操作系统使用的swap分区或swap块设备吧

rosynirvana 写了:如果压缩后的一个页面变大了
使用压缩算法压缩之后Page frame反而会变大,能举几个例子吗?什么情况下反而会变大?
看了英文版的维基百科:
https://en.wikipedia.org/wiki/Lempel%E2 ... 3Oberhumer
only expanding incompressible data by a maximum of 1/64 of the original size when measured over a block size of at least 1 kB.
意思是"对于不可压缩数据,当数据块大于或等于1k时,压缩后的数据相比原始数据最多会增加1/64"?
rosynirvana
帖子: 893
注册时间: 2011-02-14 17:46

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#13

帖子 rosynirvana » 2016-04-27 10:36

kashu 写了:
rosynirvana 写了:如果压缩后的一个页面变大了
使用压缩算法压缩之后Page frame反而会变大,能举几个例子吗?什么情况下反而会变大?
这个不用要例子吧,任何压缩算法都不能保证对于任意输入,都能减少输入数据的体积
头像
astolia
论坛版主
帖子: 6436
注册时间: 2008-09-18 13:11

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#14

帖子 astolia » 2016-04-27 11:57

1:之所以提出这个问题,好像是当时搜索结果显示zfs无法支持swap
https://wiki.archlinux.org/index.php/ZFS#Swap_volume
zfs和zswap的关系就像雷锋和雷峰塔的关系一样,你把他们扯到一起干什么。而且zfs仅仅是不支持swapfile。
It is importart to set the ZVOL block size to match the system page size
需要貌似需要设置定长数据块,但压缩需要变长数据块
设置zvol块大小和设置ssd的4k对齐一样,仅仅是出于性能考虑。
2:存储设备启用压缩的话IO吞吐量会更快:
http://blog.csdn.net/dong976209075/arti ... ls/7906687
3:貌似zfs的swap设备支持压缩?:
http://www.oschina.net/translate/runnin ... nabled-zfs
迷茫了.
你把不同的概念搅到一起当然迷茫了。吞吐量的定义是单位时间内传输的原始数据量。压缩后数据变小,而硬件最大传输速率不变,就能在单位时间内传输更多的原始数据,吞吐量当然就变大了。第二个链接哪里提到swap了?不要提到缓冲区就当成swap
swap里面本来就是放的未压缩页数据,你现在扔个压缩了的进去是什么意思?
我的理解是如果磁盘中的数据是压缩的,这样swap out时可以避免解压,swap in时读入的数据量也会较小,这意味着磁盘的硬件缓存命中率可能更高;
情况类似2中的链接.
个人观点:zswap本身就相当于一个大号的磁盘缓存,从里面换到磁盘swap的页都已经是很不常用的页了,再来个磁盘缓存保障这些很不常用的页的命中率,得到的好处比不上算法复杂度增加带来的影响。
另外,不是page frame变大,而是压缩算法在某些情况下的输出结果长度比原始数据长
具体"某些情况"我就不清楚了,我甚至不了解LZO的实现原理
跟具体的算法实现没关系,就是一个很基本的信息压缩原理的事。所有的无损压缩都是在设法减少数据信息的统计冗余。任何无损压缩算法,都只能将统计冗余减到一定程度,就没办法继续减少了。再加上一些额外的数据来描述压缩时的动态参数以方便解压,就导致了压缩后的整体大小反而比压缩前大。
rosynirvana
帖子: 893
注册时间: 2011-02-14 17:46

Re: 为什么zswap在writeback时要先解压,而非直接将压缩数据写到swap设备?

#15

帖子 rosynirvana » 2016-04-27 13:06

科学之子 写了: "备用swap设备"是什么意思?指的是缓冲区?

如果压缩后页面变大了,那应该立即抛弃压缩结果,用原始数据啊,不然存在zpool里面也是浪费额外空间
备用swap设备是文档中的backing swap device,就是一个swap device

你说的是对的,压缩率很差的数据会被拒绝

zswap是frontswap的一个后端,frontswap是通过swap_writepage和swap_readpage接入内核的
如果zswap的数据已经被写入了backing swap device,frontswap向zswap查询时候会失败,swap_readpage向frontswap查询也就失败了,这时候swap_readpage会像frontswap不存在一样直接从swap device把页面信息读回来

这样做可以保持代码简单,而且保证swap_readpage效率不比原来没有frontswap的时候差
回复