rcu_read_lock的实现是禁用preempt和barrier。并且softirq上下文不会被抢占。 所以有必要在softirq上下文中调用rcu_read_lock。障碍重要吗?
答案 0 :(得分:1)
是的,有必要使用forEach(function(eachDoc){});
来访问受rcu保护的指针,即使在softirq上下文中也是如此。
正如您所指出的,rcu_read_lock
和softirqs的某些实现(例如:TINY_RCU)使得即使您没有使用{{1分隔rcu读取端关键部分也不存在损坏风险}}。但是,这不是rcu api的保证,只是因为具体实施而“破解”。这个hack可能会破坏rcu的不同实现(例如:PREEMPT_RCU)。
如果您希望将softirqs视为显式rcu读取端关键部分,则必须使用RCU-sched api: Documentation/RCU/whatisRCU.txt
RCU主要作者撰写的文章的以下部分直接解决了您的问题: Requirements for RCU part 1: the fundamentals - Disabling preemption does not block grace periods
如果CONFIG_PROVE_RCU = y,我会在rcu_read_lock
之外添加rcu_read_lock
代码会触发lockdep警告。
答案 1 :(得分:0)
rcu_read_lock是为了保护一些同时修改的内核资源,导致竞争条件错误。
资源必须防止的是:由两个软件任务/上下文同时使用和修改。
在Linux中,同时修改可能发生在:
单核CPU环境中的事件,1)和2)可能仍会发生。 在修改关键资源的任务时,软件IRQ上升,进入软件IRQ上下文,运行IRQ处理程序并同时修改相同的资源。
答案 2 :(得分:0)
出于文档目的,最好在using System;
using Sandbox.Data;
using System.Linq;
namespace Sandbox.Console
{
class Program
{
static void Main(string[] args)
{
using (var dataContext = new SandboxDataContext())
{
try
{
var myValueList = dataContext.Numbers.Select(x => new MyValue
{
Type = DoIt(x.Value),
}).ToList();
System.Console.WriteLine("DoIt Succeeded, found {0} results", myValueList.Count);
}
catch (NotSupportedException)
{
System.Console.WriteLine("DoIt Failed, oh noes!");
}
try
{
var myValueList = dataContext.Numbers.Select(x => new MyValue
{
Type = ToValueType(x.Value),
}).ToList();
System.Console.WriteLine("ToValueType Succeeded, found {0} results", myValueList.Count);
}
catch (NotSupportedException)
{
System.Console.WriteLine("ToValueType Failed, oh noes!");
}
System.Console.ReadKey();
}
}
public static MyValueType DoIt(int value)
{
return MyValueType.SpecialType;
}
public static MyValueType ToValueType(int value)
{
return MyValueType.SpecialType;
}
public sealed class MyValue
{
public MyValueType Type { get; set; }
}
public enum MyValueType
{
SpecialType,
}
}
}
上下文中调用rcu_read_lock
,以便您和其他开发人员知道RCU
受保护的数据在这里使用。