Re: New pagg/job patches available

Peter Williams <[email protected]>
Newsgroups gmane.linux.process-aggregates
Message-ID <[email protected]>
Erik Jacobson wrote:
> Thanks.
> 
> Let me digest this and perhaps have some time to discuss it with a couple
> of my co-workers.  I did get this and will get back to you.
> 
> Erik
> 
> On Wed, 5 May 2004, Peter Williams wrote:
> 
> 
>>Erik Jacobson wrote:
>>
>>>There are new pagg and job patches available for 2.4.26 and 2.6.5
>>>kernels.
>>>
>>>I went through a couple sets of changes based on suggestions from LMKL
>>>with most of the suggestions coming from Christoph Hellwig.
>>>
>>>Because changes include removing and renaming macros and functions, the
>>>new job patch requires the new pagg patch.  In other words, if you wish
>>>to use the job patch, be sure you match it with the proper version of
>>>the PAGG.
>>>
>>>I updated the README to show the pairs.
>>>
>>>I have one more batch of changes to implement yet.
>>>
>>>Thanks!
>>>
>>>You can find the new patches on oss.sgi.com/projects/pagg
>>>Click on 'download' on the left.
>>>
>>>--
>>>Erik Jacobson - Linux System Software - Silicon Graphics - Eagan, Minnesota
>>>
>>>
>>
>>Please find attached a patch which is a first pass at a "safe to block"
>>method for calling the init() function during client registration.  The
>>way in which this patch handles kmalloc() failures needs to be improved
>>but I think this could benefit from input from someone more familiar
>>with PAGG than I am.
>>

I finally got around to testing this patch and found a few errors (not 
the least of which was calling semaphores inside a spinlock :-().  The 
enclosed patch fixes those problems and has passed some gentle testing.
pagg_init.patch (text/plain, 3.4 KB)
Index: Linux-2.6.5/kernel/pagg.c
diff -c Linux-2.6.5/kernel/pagg.c:1.1.4.1 Linux-2.6.5/kernel/pagg.c:1.1.4.1.2.2
*** Linux-2.6.5/kernel/pagg.c:1.1.4.1	Wed May  5 15:36:45 2004
--- Linux-2.6.5/kernel/pagg.c	Wed May 19 20:24:46 2004
***************
*** 202,207 ****
--- 202,304 ----
  
  	/* Okay, we can insert into the pagg hook list */
  	list_add_tail(&pagg_hook_new->entry, &pagg_hook_list);
+ 	/* Now we can call the initialiser function (if present) for each task */
+ 	if (pagg_hook_new->init != NULL) {
+ 		int num_inited = 0;
+ 
+ 		/* Because of internal race conditions we can't gaurantee
+ 		 * getting every task in just one pass so we just keep going 
+ 		 * until we don't find any unitialised tasks.  The inefficiency
+ 		 * of this should be tempered by the fact that this happens
+ 		 * at most once for each registered client.
+ 		 */
+ 		do {
+ 			struct task_struct *p = NULL;
+ 			int *live_pids;
+ 			int live_pids_sz;
+ 			int i, nump;
+ 			int failed_pid_mallocs = 0;
+ 			int failed_pagg_mallocs = 0;
+ 
+ retry_malloc:
+ 			live_pids_sz = nr_threads + 16;
+ 			live_pids = kmalloc(sizeof(int) * live_pids_sz, GFP_KERNEL);
+ 			if (live_pids == NULL) {
+ 				/* This should be changed to abort the registration
+ 				 * and undo anything that's been done.  Undoing the
+ 				 * mess may be difficult so we'll just retry for the
+ 				 * time being.
+ 				 */
+ 				if (failed_pid_mallocs < 10) {
+ 					failed_pid_mallocs++;
+ 					yield();
+ 					goto retry_malloc;
+ 				} else {
+ 					/* we can't return an error value here
+ 					 * as it would cause the module load to
+ 					 * fail while we (possibly) still hold
+ 					 * malloced memory.  So just warn that
+ 					 * initialisation has failed.  This is
+ 					 * no worse than completely ignoring
+ 					 * the initialisation function.
+ 					 */
+ 					printk(KERN_WARNING "Insufficient memory"
+ 						" to initialise"
+ 						" PAGG support (name=%s)\n",
+ 						pagg_hook_new->name);
+ 					break;
+ 				}
+ 			}
+ 			read_lock(&tasklist_lock);
+ 			if (nr_threads > live_pids_sz) {
+ 				read_unlock(&tasklist_lock);
+ 				kfree(live_pids);
+ 				goto retry_malloc;
+ 			}
+ 			nump = 0;
+ 			for_each_process(p) {
+ 				live_pids[nump] = p->pid;
+ 				nump++;
+ 			}
+ 			read_unlock(&tasklist_lock);
+ 			num_inited = 0;
+ 			for (i = 0; i < nump; i++) {
+ 				read_lock(&tasklist_lock);
+ 				if (likely((p = find_task_by_pid(live_pids[i])) != NULL))
+ 					get_task_struct(p);
+ 				read_unlock(&tasklist_lock);
+ 				if (likely(p != NULL)) {
+ 					struct pagg *paggp;
+ 
+ 					down_read(&p->pagg_list.sem);
+ 					paggp = pagg_get(p, pagg_hook_new->name);
+ 					up_read(&p->pagg_list.sem);
+ 
+ 					if (paggp == NULL) {
+ 						down_write(&p->pagg_list.sem);
+ 						paggp = pagg_alloc(p, pagg_hook_new);
+ 						if (paggp != NULL)
+ 							pagg_hook_new->init(p, paggp);
+ 						else
+ 							failed_pagg_mallocs++;
+ 						up_write(&p->pagg_list.sem);
+ 						num_inited++;
+ 					}
+ 					put_task_struct(p);
+ 				}
+ 			}
+ 			kfree(live_pids);
+ 			if (failed_pagg_mallocs > 10) {
+ 				/* we can't return an error value here
+ 				 * for the same reason as above.
+ 				 */
+ 				printk(KERN_WARNING "Insufficient memory"
+ 					" to initialise PAGG support (name=%s)\n",
+ 					pagg_hook_new->name);
+ 				break;
+ 			}
+ 		} while (num_inited > 0);
+ 	}
  	up_write(&pagg_hook_list_sem);
  
  	printk(KERN_INFO "Registering PAGG support for (name=%s)\n",
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.