All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jim Houston <jim.houston@attbi.com>
To: ak@suse.de, linux-kernel@vger.kernel.org, george@mvista.com
Subject: Re: POSIX clocks & timers - more choices
Date: Sun, 20 Oct 2002 01:40:49 -0400	[thread overview]
Message-ID: <200210200540.g9K5enl08075@linux.local> (raw)


Hi Andi, George


> > > +     if (p->ary[bit] && p->ary[bit]->bitmap == (typeof(p->bitmap))-1)
> The typeof() cast looks weird. I had to think twice to make sense of it.

I looked this again today.  When I wrote this I was trying to compare
the effect of different ID_BITS value.  Normally I would use 
(1 << ID_BITS)-1 to generate a mask but I think this breaks for 
32 bits.  I completely forgot doing this.

I have been working on solving the issue of locking around the 
find_task_by_pid().  I'm attaching a first cut at a patch.  It is
against George's version of the driver.  I'm closing the race
between one thread creating a timer for another and that thread
exiting.  It took a change to exit_itimers() so that I decide that
the process is exiting even though it has not yet unlinked its self
from the pid hash.  If the exiting process has already called
exit_itimers() we need to fail the timer create.

This is a something like this should work patch.  I have been
debugging an equivalent patch for my version and it still doesn't work
yet.

Jim Houston - Concurrent Computer Corp.

diff -urN x1.old/kernel/posix-timers.c x1.new/kernel/posix-timers.c
--- x1.old/kernel/posix-timers.c	Sat Oct 19 16:04:47 2002
+++ x1.new/kernel/posix-timers.c	Sat Oct 19 17:05:38 2002
@@ -535,7 +535,7 @@
 	int error = 0;
 	struct k_itimer *new_timer = NULL;
 	int new_timer_id;
-	struct task_struct * process = current;
+	struct task_struct * process = 0;
 	sigevent_t event;
 
 	/* Right now, we only support CLOCK_REALTIME for timers. */
@@ -547,13 +547,42 @@
 
 	spin_lock_init(&new_timer->it_lock);
 	IF_ABS_TIME_ADJ(INIT_LIST_HEAD(&new_timer->abs_list));
+	/*
+	 * return the timer_id now.  The next step is hard to 
+	 * back out.
+	 */
+	new_timer_id = new_timer->it_id;
+	if (copy_to_user(created_timer_id, 
+			 &new_timer_id, 
+			 sizeof(new_timer_id))) {
+		error = -EFAULT;
+		goto out;
+	}
 	if (timer_event_spec) {
 		if (copy_from_user(&event, timer_event_spec,
 				   sizeof(event))) {
 			error = -EFAULT;
 			goto out;
 		}
-		if ((process = good_sigevent(&event)) == NULL) {
+		read_lock(&tasklist_lock);
+		if ((process = good_sigevent(&event))) {
+			/*
+			 * We may be setting up this process for another
+			 * thread.  It may be exitiing.  To catch this
+			 * case the we clear posix_timers.next in 
+			 * exit_itimers.
+			 */
+			spin_lock(&process->alloc_lock);
+			if (!process->posix_timers.next) {
+				list_add(&new_timer->list, &process->posix_timers);
+				spin_unlock(&process->alloc_lock);
+			} else {
+				spin_unlock(&process->alloc_lock);
+				process = 0;
+			}
+		}
+		read_unlock(&tasklist_lock);
+		if (!process) {
 			error = -EINVAL;
 			goto out;
 		}
@@ -565,6 +594,10 @@
 		new_timer->it_sigev_notify = SIGEV_SIGNAL;
 		new_timer->it_sigev_signo = SIGALRM;
 		new_timer->it_sigev_value.sival_int = new_timer->it_id;
+		process = current;
+		spin_lock(&process->alloc_lock);
+		list_add(&new_timer->list, &process->posix_timers);
+		spin_unlock(&process->alloc_lock);
 	}
 
 	new_timer->it_clock = which_clock;
@@ -576,18 +609,6 @@
 	new_timer->it_timer.function = posix_timer_fn;
 	set_timer_inactive(new_timer);
 
-	new_timer_id = new_timer->it_id;
-
-	if (copy_to_user(created_timer_id, 
-			 &new_timer_id, 
-			 sizeof(new_timer_id))) {
-		error = -EFAULT;
-		goto out;
-	}
-	spin_lock(&process->alloc_lock);
-	list_add(&new_timer->list, &process->posix_timers);
-
-	spin_unlock(&process->alloc_lock);
 	/*
 	 * Once we set the process, it can be found so do it last...
 	 */
@@ -600,6 +621,24 @@
 	return error;
 }
 
+
+inline void exit_itimers(struct task_struct *tsk)
+{
+	struct	k_itimer *tmr;
+
+	/* exit_itimers - can only be called once? */
+	if (!tsk->posix_timers.next)
+		BUG():
+	spin_lock(&tsk->alloc_lock);
+	while (tsk->posix_timers.next != &tsk->posix_timers){
+		spin_unlock(&tsk->alloc_lock);
+		 tmr = list_entry(tsk->posix_timers.next,struct k_itimer,list);
+		itimer_delete(tmr);
+		spin_lock(&tsk->alloc_lock);
+	}
+	tsk->posix_timers.next = 0;
+	spin_unlock(&tsk->alloc_lock);
+}
 
 /* good_timespec
  *

             reply	other threads:[~2002-10-20  5:35 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-10-20  5:40 Jim Houston [this message]
     [not found] <200210190252.g9J2quf16153@linux.local.suse.lists.linux.kernel>
2002-10-19  3:34 ` POSIX clocks & timers - more choices Andi Kleen
2002-10-19  6:40   ` Jim Houston
2002-10-20  3:49     ` Andi Kleen
2002-10-19  6:59   ` george anzinger
2002-10-20  3:50     ` Andi Kleen
  -- strict thread matches above, loose matches on Subject: below --
2002-10-19  2:52 Jim Houston

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200210200540.g9K5enl08075@linux.local \
    --to=jim.houston@attbi.com \
    --cc=ak@suse.de \
    --cc=george@mvista.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.