2011-8-1 21:13:48

来源:互联网 发布:淘宝哪个网站领优惠券 编辑:程序博客网 时间:2024/04/30 04:48
 

 

2011-8-1 21:13:48


struct percpu_data {
 void *ptrs[NR_CPUS];
};

#define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata)

每cpu数据


void percpu_depopulate(void *__pdata, int cpu)
{
 struct percpu_data *pdata = __percpu_disguise(__pdata);

 kfree(pdata->ptrs[cpu]);
 pdata->ptrs[cpu] = NULL;
}

释放指定CPU的perCpu数据


void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask)
{
 int cpu;
 for_each_cpu_mask(cpu, *mask)
  percpu_depopulate(__pdata, cpu);
}

用掩码的形式指定一些CPU来释放数据

 

void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu)
{
 struct percpu_data *pdata = __percpu_disguise(__pdata);
 int node = cpu_to_node(cpu);

 BUG_ON(pdata->ptrs[cpu]);
 if (node_online(node)) {
  /* FIXME: kzalloc_node(size, gfp, node) */
  pdata->ptrs[cpu] = kmalloc_node(size, gfp, node);
  if (pdata->ptrs[cpu])
   memset(pdata->ptrs[cpu], 0, size);
 } else
  pdata->ptrs[cpu] = kzalloc(size, gfp);
 return pdata->ptrs[cpu];
}

如果CPU有节点就在节点上分配

static wait_queue_head_t congestion_wqh[2] = {
  __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
  __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
 };


有2个阻塞队列

void clear_bdi_congested(struct backing_dev_info *bdi, int rw)
{
 enum bdi_state bit;
 wait_queue_head_t *wqh = &congestion_wqh[rw];

 bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
 clear_bit(bit, &bdi->state);
 smp_mb__after_clear_bit();
 if (waitqueue_active(wqh))
  wake_up(wqh);
}

清除阻塞队列 唤醒阻塞进程

void set_bdi_congested(struct backing_dev_info *bdi, int rw)
{
 enum bdi_state bit;

 bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
 set_bit(bit, &bdi->state);
}

设置阻塞

long congestion_wait(int rw, long timeout)
{
 long ret;
 DEFINE_WAIT(wait);
 wait_queue_head_t *wqh = &congestion_wqh[rw];

 prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
 ret = io_schedule_timeout(timeout);
 finish_wait(wqh, &wait);
 return ret;
}

把自己加入到等待队列中,并设置阻塞超时

long congestion_wait_interruptible(int rw, long timeout)
{
 long ret;
 DEFINE_WAIT(wait);
 wait_queue_head_t *wqh = &congestion_wqh[rw];

 prepare_to_wait(wqh, &wait, TASK_INTERRUPTIBLE);
 if (signal_pending(current))
  ret = -ERESTARTSYS;
 else
  ret = io_schedule_timeout(timeout);
 finish_wait(wqh, &wait);
 return ret;
}

可信号唤醒的阻塞等待

void congestion_end(int rw)
{
 wait_queue_head_t *wqh = &congestion_wqh[rw];

 if (waitqueue_active(wqh))
  wake_up(wqh);
}

阻塞结束

 

原创粉丝点击