[lkml]   [2021]   [Apr]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
SubjectRe: [PATCH 00/13] [RFC] Rust support
On 16/04/21 17:58, Theodore Ts'o wrote:
> Another fairly common use case is a lockless, racy test of a
> particular field, as an optimization before we take the lock before we
> test it for realsies. In this particular case, we can't allocate
> memory while holding a spinlock, so we check to see without taking the
> spinlock to see whether we should allocate memory (which is expensive,
> and unnecessasry most of the time):
> alloc_transaction:
> /*
> * This check is racy but it is just an optimization of allocating new
> * transaction early if there are high chances we'll need it. If we
> * guess wrong, we'll retry or free the unused transaction.
> */
> if (!data_race(journal->j_running_transaction)) {
> /*
> * If __GFP_FS is not present, then we may be being called from
> * inside the fs writeback layer, so we MUST NOT fail.
> */
> if ((gfp_mask & __GFP_FS) == 0)
> gfp_mask |= __GFP_NOFAIL;
> new_transaction = kmem_cache_zalloc(transaction_cache,
> gfp_mask);
> if (!new_transaction)
> return -ENOMEM;
> }

From my limited experience with Rust, things like these are a bit
annoying indeed, sooner or later Mutex<> just doesn't cut it and you
have to deal with its limitations.

In this particular case you would use an AtomicBool field, place it
outside the Mutex-protected struct, and make sure that is only accessed
under the lock just like in C.
One easy way out is to make the Mutex protect (officially) nothing, i.e.
Mutex<()>, and handle the mutable fields yourself using RefCell (which
gives you run-time checking but has some some space cost) or UnsafeCell
(which is unsafe as the name says). Rust makes it pretty easy to write
smart pointers (Mutex<>'s lock guard itself is a smart pointer) so you
also have the possibility of writing a safe wrapper for the combination
of Mutex<()> and UnsafeCell.

Another example is when yu have a list of XYZ objects and use the same
mutex for both the list of XYZ and a field in struct XYZ. You could
place that field in an UnsafeCell and write a function that receives a
guard for the list lock and returns the field, or something like that.
It *is* quite ugly though.

As an aside, from a teaching standpoint associating a Mutex with a
specific data structure is bad IMNSHO, because it encourages too
fine-grained locking. Sometimes the easiest path to scalability is to
use a more coarse lock and ensure that contention is extremely rare.
But it does work for most simple use cases (and device drivers would
qualify as simple more often than not).


 \ /
  Last update: 2021-04-17 17:13    [W:0.289 / U:0.348 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site