Chinaunix首页 | 论坛 | 博客
  • 博客访问: 520374
  • 博文数量: 52
  • 博客积分: 1223
  • 博客等级: 少尉
  • 技术积分: 751
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-23 21:32
文章分类

全部博文(52)

文章存档

2016年(1)

2015年(5)

2013年(1)

2012年(45)

分类: LINUX

2012-12-26 15:57:33

1、网上的一个deadlock
idle_worker_rebind() path HOTPLUG path
online
rebind_workers()
wait_event(gcwq->rebind_hold)
woken up but no scheduled rebind_workers() returns (*)
the same cpu offline
the same cpu online again
rebind_workers()
set WORKER_REBIND
scheduled,see the WORKER_REBIND
wait rebind_workers() clear it <--bug--> wait idle_worker_rebind()
rebound.

The two thread wait each other. It is bug

这个bug在我下载的内核中应该已经修掉了,因为在rebind_workers函数中,wake_up_all(&gcwq->rebind_hold);之后,加入了如下代码:
____if (--idle_rebind.cnt) {
________spin_unlock_irq(&gcwq->lock);
________wait_for_completion(&idle_rebind.done);
________spin_lock_irq(&gcwq->lock);
____}
保证了在idle_worker_rebind()运行完成之前,rebind_workers()会一直等待不会退出。

2、引入线程池
使用worker_pool来管理,每个cpu有两个线程池,另外还有两个unbound线程池,每个线程池里至少有一个线程。

线程池的管理,大家都知道线程状态粗略的分为运行态(所谓运行态表示可以运行,在运行队列中,并不表示其正在运行)和等待态,
我们使用pool_nr_running来统计该线程池中有多少个处于运行态。当线程池中处于可运行状态的线程很多时,新创建的线程,就会处于TASK_INTERRUPTIBLE的睡眠状态。
那么处于TASK_INTERRUPTIBLE状态的线程什么时候变成可运行态呢?有以下几个触发点:
1)、insert_work
____if (__need_more_worker(pool))
________wake_up_worker(pool);
2)、idle_worker_timeout(这个函数主要是用来管理线程池中的线程的个数,当线程池中线程的个数很多时,就删除掉一些线程)
____if (too_many_workers(pool)) {
________struct worker *worker;
________unsigned long expires;

________/* idle_list is kept in LIFO order, check the last one */
________worker = list_entry(pool->idle_list.prev, struct worker, entry);
________expires = worker->last_active + IDLE_WORKER_TIMEOUT;

________if (time_before(jiffies, expires))
____________mod_timer(&pool->idle_timer, expires);
________else {
____________/* it's been idle for too long, wake up manager */
____________pool->flags |= POOL_MANAGE_WORKERS;
____________wake_up_worker(pool);
________}
____}


3、关键是rebind_workers()是干什么用的?

阅读(2415) | 评论(0) | 转发(0) |
0

上一篇:arm smp 记录

下一篇:cpu热插拔的FAQ

给主人留下些什么吧!~~