All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jim Houston <jim.houston@attbi.com>
To: Andi Kleen <ak@suse.de>
Cc: linux-kernel@vger.kernel.org
Subject: Re: POSIX clocks & timers - more choices
Date: Sat, 19 Oct 2002 02:40:27 -0400	[thread overview]
Message-ID: <3DB0FE5B.5BAA2BDB@attbi.com> (raw)
In-Reply-To: p73r8ennltj.fsf@oldwotan.suse.de

Andi Kleen wrote:
> 
> Jim Houston <jim.houston@attbi.com> writes:
> 
> > +struct id_layer {
> > +     unsigned int    bitmap: (1<<ID_BITS);
> 
> The bitfield is a bit weird here and the compiler will pad the
> field anyways always to unsigned int because of the aligned
> pointer next. It could potentially generate bad code.
> What's the rationale ?
> 

Hi Andi,

Thanks for the review.  I will try to answer your questions 
as inline.

The idea of declaring the bitmap with a field width was to
give an error if ID_BITS was made larger than the sizeof(int).
It would probably make more sense to set ID_BITS from
sizeof(int) or use an array for the bitmap and allow an
arbitrary value.

> > +     struct id_layer *ary[1<<ID_BITS];
> 
> > +void *id_lookup(struct id *idp, int id);
> > +int id_new(struct id *idp, void *ptr);
> > +void id_remove(struct id *idp, int id);
> > +void id_init(struct id *idp, int min_wrap);
> 
> Looks a bit like namespace pollution. Perhaps a bit more descriptive
> names ?

Coming up with good names is always hard.  Here is what they mean
what should they be called?

id_lookup - returns a pointer associated with an id value.
id_new - allocates a new id.  It returns the id and  
	saves the poiner in its data structure.
id_remove - frees the id and breaks the association between 
	the id and the pointer.
id_init - Initializes a "struct id" which is the basis for
	this id translation.
> 
> > +{
> > +     if (p->ary[bit] && p->ary[bit]->bitmap == (typeof(p->bitmap))-1)
> 
> Without bitfield this would look much less weird.
> 
> I would recommend using the bitops.h primitives for such stuff anyways.

I will.  This does look wierd, is this my code?

> 
> > + * Since we can't allocate memory with spinlock held and dropping the
> > + * lock to allocate gets ugly keep a free list which will satisfy the
> > + * worst case allocation.
> > + */
> > +
> > +struct id_layer *id_free;
> > +int id_free_cnt;
> > +
> > +static inline struct id_layer *alloc_layer(void)
> > +{
> 
> Standard way would be a mempool. Or better
> preallocation before you get the locks.

I prototyped this code in user space and then started thinking
about locking.  How is what I'm doing different than pre-allocating
before locking.  I would still need to lock and re-check that I
had enough data structures pre-allocated and loop.

> > +     if (id <= 0)
> > +             return(NULL);
> > +     id--;
> > +     spin_lock_irq(&id_lock);
> 
> Shouldn't this be irqsave ? Otherwise there could be hard to track
> down bugs later with this code turning on interrupts for other code
> by accident.

My assumption is that the id stuff would only be used from
code where I know interrupts are enabled. Saving the flags 
wouldn't hurt though.

> Overall I'm not sure all this radix tree stuff is worth the overhead
> and code complexity. Is just a bitmap with find_first_bit() and
> a last hit cache too slow ? How many timers do you expect to maintain ?
> 
> It looks like a similar problem to what kernel/pid.c does. If you're
> really determined to have an complicated implementation I would
> recommend seeing if you could share code with that.

When I wrote it I had hoped that it could be used for get_pid. See
my post:
http://marc.theaimsgroup.com/?l=linux-kernel&m=102916884821920&w=2

I guess the argument is that this approach is memory efficient 
and scales well for all possible id -> kernel pointer mappings.

> 
> > +struct k_clock {
> > +     struct timer_pq pq;
> > +     int  res;                       /* in nano seconds */
> 
> Hopefully it never overflows.

It better not its the resolution of the timer. Only a problem
if Hz is less than 1.

> 
> > +             default:
> > +                     printk(KERN_WARNING "sending signal failed: %d\n", ret);
> 
> printk should be removed or at least rate limited, because it could
> make the system unusable
> 
> > +/*
> > + * For some reason mips/mips64 define the SIGEV constants plus 128.
> > + * Here we define a mask to get rid of the common bits.       The
> > + * optimizer should make this costless to all but mips.
> > + */
> > +#if (ARCH == mips) || (ARCH == mips64)
> > +#define MIPS_SIGEV ~(SIGEV_NONE & \
> > +                   SIGEV_SIGNAL & \
> > +                   SIGEV_THREAD &  \
> > +                   SIGEV_THREAD_ID)
> > +#else
> > +#define MIPS_SIGEV (int)-1
> > +#endif
> 
> This definitely needs to be cleaned up.
> 
> > +{
> > +     struct task_struct * rtn = current;
> > +
> > +     if (event->sigev_notify & SIGEV_THREAD_ID & MIPS_SIGEV ) {
> > +             if ( !(rtn =
> > +                    find_task_by_pid(event->sigev_notify_thread_id)) ||
> 
> Are you holding any locks or how do you make sure rtn doesn't go away ?
> 

Good point.  It looks like  find_task_by_pid() needs to be protected
by a read_lock(&tasklist_lock).  The timers are linked into
a list so they will be removed when the process exits.  
Any sugestions on a code example that does this right are
welcome:-) 

> > +
> > +
> > +static struct k_itimer * alloc_posix_timer(void)
> > +{
> > +     struct k_itimer *tmr;
> > +     tmr = kmem_cache_alloc(posix_timers_cache, GFP_KERNEL);
> > +     memset(tmr, 0, sizeof(struct k_itimer));
> 
> Needs a NULL check.

O.K. You caught me being lazy.  I have the same problem in the 
id code as well.

> 
> Overall your code looks like overkill to me. I think it would
> be better to start with a simple implementation and only add
> all the complicated data structures if it should really be a
> bottle neck in some real world load. It also needs some cleanup
> to remove dead code etc.
> 
> -Andi

Thanks for the review.  

Jim Houston - Concurrent Computer Corp.

  reply	other threads:[~2002-10-19  6:34 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [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 [this message]
2002-10-20  3:49     ` Andi Kleen
2002-10-19  6:59   ` george anzinger
2002-10-20  3:50     ` Andi Kleen
2002-10-20  5:40 Jim Houston
  -- 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=3DB0FE5B.5BAA2BDB@attbi.com \
    --to=jim.houston@attbi.com \
    --cc=ak@suse.de \
    --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.