- 论坛徽章:
- 0
|
最近刚入门linux。主要是看驱动相关的,目前在看网卡收包的过程。也看了napi模式的收包。但是现在比较疑惑napi结构体和设备的对应关系是什么啊?是一个napi_struct对应一个网卡,还是一个napi_struct对应一个队列?
以及在do_IRQ中:
irq_enter()和irq_exit()的作用就是为了进入和退出硬中断上下文吗?(进入硬中断上下文其他中断就没办法抢占了,linux新版本禁止内核抢占?)
unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
/* high bit used in ret_from_ code */
unsigned vector = ~regs->orig_ax;
unsigned irq;
exit_idle();
irq_enter();
irq = __this_cpu_read(vector_irq[vector]);
//省略了中间的代码
irq_exit();
set_irq_regs(old_regs);
return 1;
}
在软中断处理函数net_rx_action中:
几处local_irq_disable和local_irq_enable的作用是什么啊?我看书上说这两个函数的功能是禁止/激活cpu本地中断的传递?那他会影响网卡中断吗?
static void net_rx_action(struct softirq_action *h)
{
struct softnet_data *sd = &__get_cpu_var(softnet_data);
unsigned long time_limit = jiffies + 2;
int budget = netdev_budget;
void *have;
local_irq_disable();
while (!list_empty(&sd->poll_list)) {
struct napi_struct *n;
int work, weight;
if (unlikely(budget <= 0 || time_after(jiffies, time_limit)))
goto softnet_break;
local_irq_enable();
n = list_first_entry(&sd->poll_list, struct napi_struct, poll_list);
have = netpoll_poll_lock(n);
weight = n->weight;
work = 0;
if (test_bit(NAPI_STATE_SCHED, &n->state)) {
work = n->poll(n, weight);
trace_napi_poll(n);
}
WARN_ON_ONCE(work > weight);
budget -= work;
local_irq_disable();
if (unlikely(work == weight)) {
if (unlikely(napi_disable_pending(n))) {
local_irq_enable();
napi_complete(n);
local_irq_disable();
} else
list_move_tail(&n->poll_list, &sd->poll_list);
}
netpoll_poll_unlock(have);
}
out:
net_rps_action_and_irq_enable(sd);
#ifdef CONFIG_NET_DMA
dma_issue_pending_all();
#endif
return;
softnet_break:
sd->time_squeeze++;
__raise_softirq_irqoff(NET_RX_SOFTIRQ);
goto out;
}
以及在e1000注册的软中断处理函数中为什么当一个napi的work<weight的时候,移除了napi之后,就可以重新打开网卡中断呢?
那其他napi结构体的处理不就是在开中断的环境下执行了吗?还是说一个napi结构体就对应一个网卡啊?
|
|