镇水铁牛 发表于 2015-03-30 21:18

per cpu

本帖最后由 镇水铁牛 于 2015-04-01 20:02 编辑

per cpu的实现类似数组+禁止抢占,如果原cpu id为1的线程现在被迁移到cpu id为2上,假设没有要访问per cpu数据的线程,会去运行在cpu 1上,
1. 那岂不是其原cpu id为1的数据就无法被访问了?
2. 还有它只是禁止抢占,没有禁止本地中断,如果岂不是中断中不能访问per cpu了?

nswcfd 发表于 2015-04-01 12:00

2.中断上下文会发生内核抢占吗?:em14:

nswcfd 发表于 2015-04-01 12:30

1. “假设没有要访问per cpu数据的线程,会去运行在cpu 1上,”,这句话没太理解……

=============================================

per_cpu的一个典型场景是作为counter计数。
如果不使用per_cpu,那势必要使用全局counter+全局lock或者使用atomic_add,smp下的性能受影响。
换成per_cpu,每个cpu只更新自己的counter就可以了,并且per_cpu变量的内存布局,尽量保证不同cpu的counter不共享cacheline,这样最大程度的保证性能。

关于为什么要disable抢占,我的理解是,由于更新操作不是原子的,要避免这个r-m-w序列分布在不同的cpu上来完成。

如果需要获取全局counter的值,只需要把所有cpu的局部counter遍历一下累加起来就行。
需要注意,访问其它cpu的per_cpu counter时,其它cpu还是有可能在同时更新其local counter的,所以得到的全局counter只是一个瞬间的不严格的快照而已。(可以称为“测不准”么 :p)
遍历过程本身不需要disable抢占,通常循环变量都是stack上的局部变量,就算变量线程在多个cpu之间跳来跳去,总是能保证安全完成遍历的。——也许hotplug cpu的场景除外。

镇水铁牛 发表于 2015-04-01 20:02

问题1:
      /*
       * We do not migrate tasks that are:
       * 1) running (obviously), or
       * 2) cannot be migrated to this CPU due to cpus_allowed, or
       * 3) are cache-hot on their current CPU.
       */
问题2:
      如果你真要在中断中访问per cpu,范例如下:
                    local_irq_save(flags);
                pvec = &__get_cpu_var(lru_rotate_pvecs);
                if (!pagevec_add(pvec, page))
                        pagevec_move_tail(pvec);
                local_irq_restore(flags);

nswcfd 发表于 2015-04-02 10:36

2. 可以看一下 Document/local_ops.txt

- Preemption (or interrupts) must be disabled when using local ops in
process context to   make sure the process won't be migrated to a
different CPU between getting the per-cpu variable and doing the
actual local op.
- When using local ops , no special care must be
taken on a mainline kernel, since they will run on the local CPU [with
preemption already disabled]. I suggest, however, to explicitly
disable preemption anyway to make sure it will still work correctly on
-rt kernels.

您举的这个例子,入口/出口用到了irq_save/irq_restore,说明这段代码即可被用在interrupt context,也可用在process context。
如果仅用在interrupt context,就没有必要save和restore了。

不过也许您讨论的上下文是-rt内核,那上面那段话就不成立了。

回复 4# 镇水铁牛


   

镇水铁牛 发表于 2015-04-02 20:30

回复 5# nswcfd
我把2.6初期的内核和最新的内核对比着看,是有很大差异。

   
页: [1]
查看完整版本: per cpu