首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nfconntrack全局锁的优化

nfconntrack全局锁的优化

作者头像
glinuxer
发布2019-04-10 15:03:15
1.3K0
发布2019-04-10 15:03:15
举报

nfconntrack是netfilter中的重要模块,很多netfilter的功能都依赖于这个模块,如NAT等。而利用linux来构建的网络设备,可以说,其80%的功能都依赖于nfconntrack实现的会话管理。所以,会话管理的性能优劣会对网络设备的性能产生直接的影响。

在网络设备中,对性能影响比较显著的就是锁的使用。可以说,网络设备的性能优化,很大程度上都是对于锁的优化。

nfconntrack中一个最重要的锁,就是全局的nf_conntrack_lock。这个锁的作用是保护全局会话表。当CPU尝试用当前数据包skb进行会话匹配,或者准备插入新的会话时,都需要对nf_conntrack_lock进行上锁。试想,在大流量的环境中,每个经过设备的数据包都要进行会话匹配,在多核的情况下,对这个锁的竞争是非常激烈的。

这是commiter做这个优化时,使用perf对内核进行的profile,可以清楚的看到对这个锁的spin_lock占用了大量的CPU,是性能的主要瓶颈。 —— 笔者以前从事的就是网络设备的开发工作,之前一直没有想到nfconntrack居然使用了这么长时间的一个全局锁。对于设备厂商来说,这个是早就应该进行的优化。

当确定nf_conntrack_lock全局锁为性能瓶颈时,我们应该怎样优化呢?这个问题可以一般化为,如何优化一个锁?最理想的情况,就是去掉这个锁。实现这个目的,一般可以使用空间换时间,或者使用无锁算法。对于会话表来说,锁是充分且必要的。因为必须要保证会话在会话表中的唯一性,查询和插入必须是原子的,不可中断的。因此必须使用锁来保证安全。第二条路,就是减小锁的粒度。这个也是这个优化的主要思想。

netfilter的会话,被分为两个部分,一个是original tuple,另外一个是reply tuple,两个tuple分别要插入两个不同的hash表中,用于两个方向上的匹配。现在要减小锁的粒度,最直观的想法是,将以前的全局锁,变成基于桶的锁,一个hash桶就使用一个锁。这个想法,从思路上是没有问题的,但是对于会话表来说,其桶的个数一般很大。

通过上面的命令,可以得到linux默认的nfconntrack的桶的个数。对于网络设备来说,有时候还要加大桶的个数。如果每个桶一个锁的话,会消耗掉不少内存。

这个commit采用了一个折中的办法。每个锁负责保障多个桶的安全,这样就不需要一个桶对应一个锁了,这样既提高了并发性,又没有增加太多内存消耗。

其定义了一个nf_contrack_locks数组,用户可以根据自己的环境,定义不同的CONNTRACK_LOCKS大小。

当使用多个锁来保护会话表后,就容易引入deadlock问题。试想,如果有两把锁A和B,分别用于保护不同的hash表的桶的集合。假设有两个tuple,它们被插入到两个不同的hash表的桶中。其中original tuple所在的桶,由锁A保护,reply tuple所在的桶,由锁B保护。如果两个方向的数据包同时到达两个不同的CPU1和2,则CPU1已经获得了锁A,并尝试获得锁B,而CPU已经获得锁B,并尝试获得锁A。这时,两个CPU都拿到一个锁,并尝试获得对方的锁,但肯定又无法拿到,于是这两个CPU就死锁了,系统也就hang住了。这个问题是在多锁环境下,经常遇到的问题。解决的方法就是:一定要保证上锁的顺序,并保持一致。

下面看看这个commit是如何解决这个问题的。

  1. 创建了一个新的函数nf_conntrack_double_lock用于封装上锁动作,保证所有代码使用一致的策略。
  2. 对于两个锁,每次上锁的时候,都是先获取索引较小的锁,再获取索引较大的锁。
  3. 判断两个锁的索引是否一致,避免对同一个锁进行两次上锁的操作。

通过上面3个技巧,就保证了新的nf_conntrack_locks,不会产生死锁。

对于nf_conntrack_lock全局锁优化的commit是93bb0ceb75be,感兴趣的同学可以自己阅读这个patch。没记错的话,这个commit是在3.18内核版本中引入的。—— 真没想到,这么晚才有人优化这个锁:(

PS:后面会继续分析对nfcontrack中锁的优化。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-07-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LinuxerPub 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档