Re: [PATCH] Intel Management Engine Interface

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Andrew Morton
Date: Monday, August 11, 2008 - 9:53 pm

On Mon, 11 Aug 2008 21:23:01 +0200 (CEST)
Marcin Obara <marcin_obara@users.sourceforge.net> wrote:


This code adds new kernel->userspace interfaces?

Please fully document those interfaces so that we can review the
proposed design.

What follows is a low-level review.  I didn't really address the
higher-level design aspects because even having read it, I don't know
what all this code does, because I wasn't told.  I could work that out,
but I'd prefer not to have to, because that means that everyone else
who wishes to maintain this code would need to do the same thing.  That
isn't very efficient.


What's this?  The driver defines its onw errno numbers?

Are these ever returned to userspace?

This is risky/confusing/misleading, isn't it?


This macro is a bit dangerous.  If code does

	DBG("%d", foo++)

then the value of `foo' will depend upon whether or not heci_debug is set.

A programmer would need to be damn stupid to pass an
expression-with-side-effects into a debugging macro, so I don't think
anything needs to be done here.  Just sayin'.


Actually, the bigger risk is code will do

	DBG("%d", foo->bar);

and `foo' is NULL.  We don't get to find out about the bug until
someone enables runtime debugging.


I find that the most valuable code comments are those which document
the core data structures.  For each field: what its role in life is,
what its relationship is with other fields and other structures, what
its locking rules are, etc.

Right now, this reader of your code is wondering about cb_list.

- What is it?  I _think_ it's the means by which multiple instances
  of heci_cb_private are attached to a heci_file_private?

- What lock protects that list?  heci_file_private.file_lock,
  perhaps?  That was unobvious from a quick read of the code.

This stuff matters.  It's basically the first thing which a reviewer of
the design and implementation wants to know about, and that reviewer
doesn't want to have to dive intothe implementation, then
reverse-engineer the design, then go back and review how accurately the
code actually implements that design.

IOW: better code comments, please.  This is more than a cosmetic
nicety.  It is important for maintainability and for reviewability and
is worth spending quality time over.

Also, it is unusual that the code does
INIT_LIST_HEAD(heci_cb_private.cb_list) in two separate places.  Please
check that this was intended+correct+desirable.


In numerous places, this code does

	foo = (struct heci_file_private *)priv_cb_pos->file_private;

please remove all these typecasts of void*.  They are unneeded and they
actually remove type-safety.  If someone were to change priv_cb_pos to
a u8, they'll really want those compilation warnings/errors.

(OK, that's unlikely to happen, but the casts are ugly and add no
value).


Again, the roles of and the relationship between the above three
structs is key to understanding the overall driver design.


What are these?  They map onto some hardware-defined thing?  In IO
space?  DMA'ed into main memory?  Dunno.  Some explanation here would
help.


Dittoes.


What is the relationship between this code and aio?  I note that
several files include linux/aio.h, which was a bit of a surprise.  No
other drivers do that.

This part of your design was perhaps more suited to
documentation-via-changelog than via code comments.


All protected by spin_lock_bh(iamt_heci_device.device_lock), it appears.


list-heads are nasty things.  Quite anonymous, quite type-unsafe.  It's
a bit hard to tell which list_ehad gets strung onto which anchoring
list_head, and the compiler cannot tell when a programmer screws this
up.  Suitable comments will help.



What are these?

I'm surprised that they dont' have type resource_size_t or dma_addr_t
or void __iomem * or somesuch thing.

<reads the code a bit>

yup, resource_size_t.


void __iomem *?


comment needs full detailing, please.


What's this?

I see two separate sites which are doing a
PREPARE_WORK(iamt_heci_device.work).  This is quite unusual and
possibly incorrect.  Please check it all.  The one in
heci_isr_interrupt() is hopefully unneeded.


What's this?

Seems to be protected by device_lock?


See comments below.


nit: __u32 is normally only needed in data structures which are to be
included by userspace.  This structure shouldn't be visible to
userspace compilation hence it could use plain old u32.


Seems strange that the above buffers are a per-device global.  It
implies that the driver can only do one-message-at-a-time.


This is an "array", nbot a list.


"stopped"


This can have static scope.

(Please check the whole driver for needlessly-global symbols)


Part of this function's interface is most definitely "must be called
under device_lock".  That's just as worthy of documentation as the
formal argument.  Unfortunately the kernel-doc system fails to
formalise this sort of thing.

One way of firmly documenting this is assert_spin_locked().  Your call.


Can this happen?


It is unusual for a driver to unconditionally zap lots of per-device
fields like this during normal operation.


Various stray newlines..


See above comments regarding *_interruptible* dangers.


If heci_wait_event_int_timeout() got terminated due to a pending
signal, this code drops that information on the floor. 
heci_wait_event_int_timeout() will have returned before
that-which-it-was-waiting-for has happened, and I suspect that bad
things will happen.

Please check the signal_pending() behaviour in here, and try to runtime
test it.

The same goes for all foo_interruptible code sites in this driver.  It
is a dangerous function call to be used in a driver.  Few people will
remember to test the it-returned-early-due-to-signal_pending case.


"Called under spin_lock_bh(device_lock)"


kthread_stop() can sleep, hence cannnot be called from under spinlock.


The use of waitqueue_active() has well-known races, only I forget the
details.  Barrier-related, iirc.  Nick Piggin might recall the details.
We should have added a comment to waitqueue_active().


I'm surprised that we can just retrun here without having to release
any resources.


I suspect this memset wasn't needed.


Mysterious.


Unneeded and undesirable cast of void*.


A manipulation such as this must have a comment.  Because there's
really no way in whcih the reader of the code can work out why it is
there.

And a driver shouldn't be accessing PF_NOFREEZE directly.  There are
various interfaces in freezer.h whcih should be used instead (I forget
which one - it has changed a few times).



This looks racy.  It could at least do

	if (dev->reinit_tsk == current)
		dev->reinit_tsk = NULL;

but it all still seems a bit dodgy.  Perhaps reinit_tsk should be
protected by a sleeping lock (ie: a mutex).



COuld we make this code cleaner and more typesafe by defining
wr_msg_buf as a union of heci_msg_hdr, hbm_cmd, etc?


Maybe heci_write_message() should take a void*.


There seems to be a bit of code duplication here.


Can this happen?

flow_ctrl_creds() test for num_heci_me_clients == 0, whereas this code
also tests for num_heci_me_clients<0.  Which one is correct?


Strange locking.  Shouldn't we at least check to see whether some other
thread has just initialised dev->me_clients?

If that is not possible, then why is the locking needed at all?


dittoes all over the place.


Can these all happen?


That's a bit excessively parenthesised.

Can these things happen?


Use setup_timer().

Note that setup_timer() does init_timer(), but we already have an
init_timer(dev->wd_timer) elsewhere.  Please sort that out.

The taking of device_lock here surely is unneeded.

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH] Intel Management Engine Interface, Marcin Obara, (Thu Jul 17, 11:27 am)
Re: [PATCH] Intel Management Engine Interface, Randy Dunlap, (Thu Jul 17, 5:00 pm)
[PATCH] Intel Management Engine Interface, Marcin Obara, (Thu Jul 17, 10:44 pm)
Re: [PATCH] Intel Management Engine Interface, Andi Kleen, (Fri Jul 18, 2:27 am)
Re: [PATCH] Intel Management Engine Interface, Marcin Obara, (Fri Jul 18, 3:51 am)
Re: [PATCH] Intel Management Engine Interface, Andi Kleen, (Fri Jul 18, 4:02 am)
Re: [PATCH] Intel Management Engine Interface, Marcin Obara, (Fri Jul 18, 4:33 am)
Re: [PATCH] Intel Management Engine Interface, Marcin Obara, (Fri Jul 18, 10:39 am)
Re: [PATCH] Intel Management Engine Interface, Marcin Obara, (Fri Jul 18, 12:23 pm)
[PATCH] Intel Management Engine Interface, Marcin Obara, (Fri Jul 18, 1:30 pm)
[PATCH] Intel Management Engine Interface, Marcin Obara, (Wed Jul 23, 11:00 am)
Re: [PATCH] Intel Management Engine Interface, Pavel Machek, (Wed Aug 6, 9:56 am)
Re: [PATCH] Intel Management Engine Interface, Marcin Obara, (Mon Aug 11, 12:23 pm)
Re: [PATCH] Intel Management Engine Interface, Andrew Morton, (Mon Aug 11, 9:53 pm)
Re: [PATCH] Intel Management Engine Interface, Jiri Slaby, (Tue Aug 12, 9:15 am)
Re: [PATCH] Intel Management Engine Interface, Alan Cox, (Tue Aug 12, 12:24 pm)
Re: [PATCH] Intel Management Engine Interface, Marcin Obara, (Tue Aug 12, 12:24 pm)
Re: [PATCH] Intel Management Engine Interface, Arjan van de Ven, (Tue Aug 12, 2:03 pm)
Re: [PATCH] Intel Management Engine Interface, Greg KH, (Tue Aug 12, 5:58 pm)
Re: [PATCH] Intel Management Engine Interface, Marcin Obara, (Wed Aug 13, 12:16 am)
Re: [PATCH] Intel Management Engine Interface, Greg KH, (Wed Aug 13, 11:18 am)
Re: [PATCH] Intel Management Engine Interface, Marcin Obara, (Wed Aug 13, 12:48 pm)
Re: [PATCH] Intel Management Engine Interface, Greg KH, (Wed Aug 13, 5:23 pm)