Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Jan 2010 21:22:42 +0100
From:      Max Laier <max@love2party.net>
To:        freebsd-hackers@freebsd.org
Cc:        "H.Fazaeli" <fazaeli@sepehrs.com>
Subject:   Re: uiomove and mutex
Message-ID:  <201001112122.43000.max@love2party.net>
In-Reply-To: <4B4B7A7F.2090808@sepehrs.com>
References:  <4B4B7A7F.2090808@sepehrs.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Monday 11 January 2010 20:22:39 H.Fazaeli wrote:
> dear gurus
> 
> man mutex(9) states that:
> 
> "No mutexes should be held (except for Giant) across functions which
> access memory in userspace, such as copyin(9), copyout(9), uiomove(9),
> fuword(9), etc.  No locks are needed when calling these functions."
> 
> can someone pls. explain why it is so?

Any memory access to user memory (unless the memory has been wired down 
before) can result in a swap in from secondary storage, which - in turn - 
results in a sleep.  Most locks are not allowed to be held over a sleep.

See locking(9) for details.
 
> Suppose I have a kernel buffer to which kernel writes and
> userland processes read via a character device. In the device
> read method, If we unlock the mutex just before uiomove, is it
> guaranteed that kernel does not write to the buffer in the middle
> of uiomove? If yes, how? What is the solution in such a situation?
> rwlocks? an intermediate buffer?

sx(9) is one possibility.  The other way is to use a pointer or state that you 
modify while holding the mutex:

Thread1:

  lock(&mtx);
  buffer_in_use=1;
  unlock(&mtx);

  uiomove()

  lock(&mtx);
  buffer_in_use=0;
  wakeup(&buffer_in_use);
  unlock(&mtx);

Thread2:

  lock(&mtx);
  while(buffer_in_use)
    mlseep(&buffer_in_use, &mtx, ...)
  do_stuff_to_the_buffer();
  unlock(&mtx);

--
  Max




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001112122.43000.max>