forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cause writes to cpuset "cpus" file to update cpus_allowed for member tasks: - collect batches of tasks under tasklist_lock and then call set_cpus_allowed() on them outside the lock (since this can sleep). - add a simple generic priority heap type to allow efficient collection of batches of tasks to be processed without duplicating or missing any tasks in subsequent batches. - make "cpus" file update a no-op if the mask hasn't changed - fix race between update_cpumask() and sched_setaffinity() by making sched_setaffinity() post-check that it's not running on any cpus outside cpuset_cpus_allowed(). [[email protected]: coding-style fixes] Signed-off-by: Paul Menage <[email protected]> Cc: Paul Jackson <[email protected]> Cc: David Rientjes <[email protected]> Cc: Nick Piggin <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Balbir Singh <[email protected]> Cc: Cedric Le Goater <[email protected]> Cc: "Eric W. Biederman" <[email protected]> Cc: Serge Hallyn <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
- Loading branch information
Paul Menage
authored and
Linus Torvalds
committed
Oct 19, 2007
1 parent
020958b
commit 8707d8b
Showing
5 changed files
with
243 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#ifndef _LINUX_PRIO_HEAP_H | ||
#define _LINUX_PRIO_HEAP_H | ||
|
||
/* | ||
* Simple insertion-only static-sized priority heap containing | ||
* pointers, based on CLR, chapter 7 | ||
*/ | ||
|
||
#include <linux/gfp.h> | ||
|
||
/** | ||
* struct ptr_heap - simple static-sized priority heap | ||
* @ptrs - pointer to data area | ||
* @max - max number of elements that can be stored in @ptrs | ||
* @size - current number of valid elements in @ptrs (in the range 0..@size-1 | ||
* @gt: comparison operator, which should implement "greater than" | ||
*/ | ||
struct ptr_heap { | ||
void **ptrs; | ||
int max; | ||
int size; | ||
int (*gt)(void *, void *); | ||
}; | ||
|
||
/** | ||
* heap_init - initialize an empty heap with a given memory size | ||
* @heap: the heap structure to be initialized | ||
* @size: amount of memory to use in bytes | ||
* @gfp_mask: mask to pass to kmalloc() | ||
* @gt: comparison operator, which should implement "greater than" | ||
*/ | ||
extern int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask, | ||
int (*gt)(void *, void *)); | ||
|
||
/** | ||
* heap_free - release a heap's storage | ||
* @heap: the heap structure whose data should be released | ||
*/ | ||
void heap_free(struct ptr_heap *heap); | ||
|
||
/** | ||
* heap_insert - insert a value into the heap and return any overflowed value | ||
* @heap: the heap to be operated on | ||
* @p: the pointer to be inserted | ||
* | ||
* Attempts to insert the given value into the priority heap. If the | ||
* heap is full prior to the insertion, then the resulting heap will | ||
* consist of the smallest @max elements of the original heap and the | ||
* new element; the greatest element will be removed from the heap and | ||
* returned. Note that the returned element will be the new element | ||
* (i.e. no change to the heap) if the new element is greater than all | ||
* elements currently in the heap. | ||
*/ | ||
extern void *heap_insert(struct ptr_heap *heap, void *p); | ||
|
||
|
||
|
||
#endif /* _LINUX_PRIO_HEAP_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* Simple insertion-only static-sized priority heap containing | ||
* pointers, based on CLR, chapter 7 | ||
*/ | ||
|
||
#include <linux/slab.h> | ||
#include <linux/prio_heap.h> | ||
|
||
int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask, | ||
int (*gt)(void *, void *)) | ||
{ | ||
heap->ptrs = kmalloc(size, gfp_mask); | ||
if (!heap->ptrs) | ||
return -ENOMEM; | ||
heap->size = 0; | ||
heap->max = size / sizeof(void *); | ||
heap->gt = gt; | ||
return 0; | ||
} | ||
|
||
void heap_free(struct ptr_heap *heap) | ||
{ | ||
kfree(heap->ptrs); | ||
} | ||
|
||
void *heap_insert(struct ptr_heap *heap, void *p) | ||
{ | ||
void *res; | ||
void **ptrs = heap->ptrs; | ||
int pos; | ||
|
||
if (heap->size < heap->max) { | ||
/* Heap insertion */ | ||
int pos = heap->size++; | ||
while (pos > 0 && heap->gt(p, ptrs[(pos-1)/2])) { | ||
ptrs[pos] = ptrs[(pos-1)/2]; | ||
pos = (pos-1)/2; | ||
} | ||
ptrs[pos] = p; | ||
return NULL; | ||
} | ||
|
||
/* The heap is full, so something will have to be dropped */ | ||
|
||
/* If the new pointer is greater than the current max, drop it */ | ||
if (heap->gt(p, ptrs[0])) | ||
return p; | ||
|
||
/* Replace the current max and heapify */ | ||
res = ptrs[0]; | ||
ptrs[0] = p; | ||
pos = 0; | ||
|
||
while (1) { | ||
int left = 2 * pos + 1; | ||
int right = 2 * pos + 2; | ||
int largest = pos; | ||
if (left < heap->size && heap->gt(ptrs[left], p)) | ||
largest = left; | ||
if (right < heap->size && heap->gt(ptrs[right], ptrs[largest])) | ||
largest = right; | ||
if (largest == pos) | ||
break; | ||
/* Push p down the heap one level and bump one up */ | ||
ptrs[pos] = ptrs[largest]; | ||
ptrs[largest] = p; | ||
pos = largest; | ||
} | ||
return res; | ||
} |