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",