mirror of
				https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
				synced 2025-10-31 11:03:14 +00:00 
			
		
		
		
	 8707d8b8c0
			
		
	
	
		8707d8b8c0
		
	
	
	
	
		
			
			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(). [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Paul Menage <menage@google.com> Cc: Paul Jackson <pj@sgi.com> Cc: David Rientjes <rientjes@google.com> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Balbir Singh <balbir@in.ibm.com> Cc: Cedric Le Goater <clg@fr.ibm.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
		
			
				
	
	
		
			71 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * 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;
 | |
| }
 |