On Mon, Feb 11, 2019 at 04:38:46PM +0800, Huang, Ying wrote:
> +struct swap_info_struct *get_swap_device(swp_entry_t entry)
> +{
> +     struct swap_info_struct *si;
> +     unsigned long type, offset;
> +
> +     if (!entry.val)
> +             goto out;

> +     type = swp_type(entry);
> +     si = swap_type_to_swap_info(type);

These lines can be collapsed into swp_swap_info if you want.

> +     if (!si)
> +             goto bad_nofile;
> +
> +     preempt_disable();
> +     if (!(si->flags & SWP_VALID))
> +             goto unlock_out;

After Hugh alluded to barriers, it seems the read of SWP_VALID could be
reordered with the write in preempt_disable at runtime.  Without smp_mb()
between the two, couldn't this happen, however unlikely a race it is?

CPU0                                CPU1

__swap_duplicate()
    get_swap_device()
        // sees SWP_VALID set
                                   swapoff
                                       p->flags &= ~SWP_VALID;
                                       spin_unlock(&p->lock); // pair w/ smp_mb
                                       ...
                                       stop_machine(...)
                                       p->swap_map = NULL;
        preempt_disable()
    read NULL p->swap_map

Reply via email to