pagg
[Top] [All Lists]

Re: New pagg/job patches available

To: Erik Jacobson <erikj@xxxxxxxxxxxxxxxxxxxx>
Subject: Re: New pagg/job patches available
From: Peter Williams <pwil3058@xxxxxxxxxxxxxx>
Date: Wed, 05 May 2004 16:57:41 +1000
Cc: pagg@xxxxxxxxxxx
In-reply-to: <Pine.SGI.4.53.0405041443560.8140@xxxxxxxxxxxxxxxxxxxx>
References: <Pine.SGI.4.53.0405041443560.8140@xxxxxxxxxxxxxxxxxxxx>
Sender: pagg-bounce@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624 Netscape/7.1
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.

Peter
Index: kernel/pagg.c
===================================================================
RCS file: /export/cvsroot/Linux-2.6.5/kernel/Attic/pagg.c,v
retrieving revision 1.1.4.1
diff -c -r1.1.4.1 pagg.c
*** kernel/pagg.c       5 May 2004 05:36:45 -0000       1.1.4.1
--- kernel/pagg.c       5 May 2004 06:48:03 -0000
***************
*** 202,207 ****
--- 202,305 ----
  
        /* 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;
+                       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;
+                       }
+                       num_inited = 0;
+                       for_each_process(p) {
+                               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) {
+                                       /* this one hasn't been initialised yet 
*/
+                                       live_pids[num_inited] = p->pid;
+                                       num_inited++;
+                               }
+                       }
+                       read_unlock(&tasklist_lock);
+                       for (i = 0; i < num_inited; i++) {
+                               read_lock(&tasklist_lock);
+                               if (likely((p = find_task_by_pid(i)) != NULL))
+                                       get_task_struct(p);
+                               read_unlock(&tasklist_lock);
+                               if (likely(p != NULL)) {
+                                       struct pagg *paggp;
+ 
+                                       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);
+                                       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",
<Prev in Thread] Current Thread [Next in Thread>