diff options
| author | <jgarzik@pretzel.yyz.us> | 2005-05-27 22:07:02 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-05-27 22:07:02 -0400 |
| commit | 1f15d694522af9cd7492695f11dd2dc77b6cf098 (patch) | |
| tree | 7f67a4c38456ec73359d576a5c602d18c3c3ef72 /kernel/cpuset.c | |
| parent | fff9cfd99c0f88645c3f50d7476d6c8cef99f140 (diff) | |
| parent | 254feb882a7c6e4e51416dff6a97d847fbbba551 (diff) | |
Automatic merge of /spare/repo/netdev-2.6 branch master
Diffstat (limited to 'kernel/cpuset.c')
| -rw-r--r-- | kernel/cpuset.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 961d74044deb..00e8f2575512 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
| @@ -166,9 +166,8 @@ static struct super_block *cpuset_sb = NULL; | |||
| 166 | * The hooks from fork and exit, cpuset_fork() and cpuset_exit(), don't | 166 | * The hooks from fork and exit, cpuset_fork() and cpuset_exit(), don't |
| 167 | * (usually) grab cpuset_sem. These are the two most performance | 167 | * (usually) grab cpuset_sem. These are the two most performance |
| 168 | * critical pieces of code here. The exception occurs on exit(), | 168 | * critical pieces of code here. The exception occurs on exit(), |
| 169 | * if the last task using a cpuset exits, and the cpuset was marked | 169 | * when a task in a notify_on_release cpuset exits. Then cpuset_sem |
| 170 | * notify_on_release. In that case, the cpuset_sem is taken, the | 170 | * is taken, and if the cpuset count is zero, a usermode call made |
| 171 | * path to the released cpuset calculated, and a usermode call made | ||
| 172 | * to /sbin/cpuset_release_agent with the name of the cpuset (path | 171 | * to /sbin/cpuset_release_agent with the name of the cpuset (path |
| 173 | * relative to the root of cpuset file system) as the argument. | 172 | * relative to the root of cpuset file system) as the argument. |
| 174 | * | 173 | * |
| @@ -1404,6 +1403,18 @@ void cpuset_fork(struct task_struct *tsk) | |||
| 1404 | * | 1403 | * |
| 1405 | * Description: Detach cpuset from @tsk and release it. | 1404 | * Description: Detach cpuset from @tsk and release it. |
| 1406 | * | 1405 | * |
| 1406 | * Note that cpusets marked notify_on_release force every task | ||
| 1407 | * in them to take the global cpuset_sem semaphore when exiting. | ||
| 1408 | * This could impact scaling on very large systems. Be reluctant | ||
| 1409 | * to use notify_on_release cpusets where very high task exit | ||
| 1410 | * scaling is required on large systems. | ||
| 1411 | * | ||
| 1412 | * Don't even think about derefencing 'cs' after the cpuset use | ||
| 1413 | * count goes to zero, except inside a critical section guarded | ||
| 1414 | * by the cpuset_sem semaphore. If you don't hold cpuset_sem, | ||
| 1415 | * then a zero cpuset use count is a license to any other task to | ||
| 1416 | * nuke the cpuset immediately. | ||
| 1417 | * | ||
| 1407 | **/ | 1418 | **/ |
| 1408 | 1419 | ||
| 1409 | void cpuset_exit(struct task_struct *tsk) | 1420 | void cpuset_exit(struct task_struct *tsk) |
| @@ -1415,10 +1426,13 @@ void cpuset_exit(struct task_struct *tsk) | |||
| 1415 | tsk->cpuset = NULL; | 1426 | tsk->cpuset = NULL; |
| 1416 | task_unlock(tsk); | 1427 | task_unlock(tsk); |
| 1417 | 1428 | ||
| 1418 | if (atomic_dec_and_test(&cs->count)) { | 1429 | if (notify_on_release(cs)) { |
| 1419 | down(&cpuset_sem); | 1430 | down(&cpuset_sem); |
| 1420 | check_for_release(cs); | 1431 | if (atomic_dec_and_test(&cs->count)) |
| 1432 | check_for_release(cs); | ||
| 1421 | up(&cpuset_sem); | 1433 | up(&cpuset_sem); |
| 1434 | } else { | ||
| 1435 | atomic_dec(&cs->count); | ||
| 1422 | } | 1436 | } |
| 1423 | } | 1437 | } |
| 1424 | 1438 | ||
