2.2 上下文及同步处理
WLAN驱动在不同的上下文处理中执行,比如
- ISR上下文
- Softirq(软中断)/tasklet(内核软中断延迟机制)上下文
- Process(进程)上下文
2.2.1 ISR处理
WLAN设备成功附着之后(ath_attach函数调用),驱动会为这个设备请求一个IRQ资源,并注册ath_isr中断服务例程(ISR)。驱动同时会初始化一个叫做ath_tasklet的tasklet资源。ath_isr首先会通过扫描WLAN硬件的待处理的中断,来检查这个中断是否是来自这个设备。一旦这个中断被确认是来自WLAN设备的中断,他将根据中断状态寄存器,来运用tasklet,进行中断对应的处理。有一些时间敏感的处理,比如软件beacon alert处理,UAPSD触发处理等,会在ISR上下文中直接处理。其中一些时间敏感的处理,可以在编译时,指定其在tasklet上下文中运行,运行所需的时间可以设置。ath_isr处理的最后阶段,如果tasklet开始执行,所有的WLAN设备中断会被禁用,除了那些时间敏感的中断。
2.2.2 Softirq/Tasklet处理
ath_tasklet的处理,是在tasklet上下文中执行的。ath_tasklet检查存储的中断状态值(通过ath_isr),并执行相应的动作。一些ath_tasklet的功能包括:
- 异常处理
- 传输结束处理
- 收到帧时的处理
在tasklet的最后,WLAN设备中断,会根据当前中断mask的设定值,被再次使能。网络设备上的网络帧传输,在NETIF softirq上下文中进行。所有的OS timers处理,都在TIMER softirq上下文中进行。
2.2.3 进程上下文(Process Context)
所有对驱动进行的访问,都通过运行在进程上下文中的ioctl系统接口来进行。
2.2.4 同步处理(Synchronization)
上面提到的上下文(context)之间的同步处理是必须的,因为有一些data是各个context之间share的。
大多数WLAN驱动使用的同步方法是spin_lock。Linux提供了不同类型的spin_lock,比如spin_lock、spin_lock_bh、spin_lock_irq和spin_lock_irqsave。表2-1大体描述了各个context之间使用了何种spin_lock来完成同步机制。
Table 2-1 同步方法
- | ISR | Softirq/Tasklets | Process context |
---|---|---|---|
ISR | - | spin_lock_irqsave | spin_lock_irqsave |
Softirq/Tasklets | spin_lock_irqsave | spin_lock | spin_lock_bh |
Process context | spin_lock_irqsave | spin_lock_bh | - |
驱动中使用到的其他一些同步技术有:
- 原子操作(Atomic):任何主要的操作都是uninterruptable的。
- 读写锁(Read/write lock):读写锁和spin_lock类似,但主要用于从driver中分离处理的read/write操作。Linux提供了许多和spin_lock相似的读写锁来完成context之间的同步,他们的主要思想和用法都是类似的,主要是用于不同类型的read/write操作。