Re: [PATCH v4 4/5] mm/shmem: fix infinite loop when swap in shmem error at swapoff time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, May 20, 2022 at 04:17:45PM +0800, Miaohe Lin wrote:
> On 2022/5/20 14:34, HORIGUCHI NAOYA(堀口 直也) wrote:
> > On Thu, May 19, 2022 at 08:50:29PM +0800, Miaohe Lin wrote:
> >> When swap in shmem error at swapoff time, there would be a infinite loop
> >> in the while loop in shmem_unuse_inode(). It's because swapin error is
> >> deliberately ignored now and thus info->swapped will never reach 0. So
> >> we can't escape the loop in shmem_unuse().
> >>
> >> In order to fix the issue, swapin_error entry is stored in the mapping
> >> when swapin error occurs. So the swapcache page can be freed and the
> >> user won't end up with a permanently mounted swap because a sector is
> >> bad. If the page is accessed later, the user process will be killed
> >> so that corrupted data is never consumed. On the other hand, if the
> >> page is never accessed, the user won't even notice it.
> >>
> >> Reported-by: Naoya Horiguchi <naoya.horiguchi@xxxxxxx>
> >> Signed-off-by: Miaohe Lin <linmiaohe@xxxxxxxxxx>
> > 
> > Hi Miaohe,
> > 
> > Thank you for the update.  I might miss something, but I still see the same
> > problem (I checked it on mm-everything-2022-05-19-00-03 + this patchset).
> 
> I was testing this patch on my 5.10 kernel. I reproduced the problem in my env and
> fixed it. It seems there might be some critical difference though I checked that by
> reviewing the code... Sorry. :(
> 
> > 
> > This patch has the effect to change the return value of shmem_swapin_folio(),
> > -EIO (without this patch) to -EEXIST (with this patch).
> 
> In fact, I didn't change the return value from -EIO to -EEXIST:
> 
> @@ -1762,6 +1799,8 @@ static int shmem_swapin_folio(struct inode *inode, pgoff_t index,
>  failed:
>  	if (!shmem_confirm_swap(mapping, index, swap))
>  		error = -EEXIST;
> +	if (error == -EIO)
> +		shmem_set_folio_swapin_error(inode, index, folio, swap)
> 
> > But shmem_unuse_swap_entries() checks neither, so no change from caller's view point.
> > Maybe breaking in errors (rather than ENOMEM) in for loop in shmem_unuse_swap_entries()
> > solves the issue?  I briefly checked with the below change, then swapoff can return
> > with failure.
> > 
> > @@ -1222,7 +1222,7 @@ static int shmem_unuse_swap_entries(struct inode *inode,
> >                         folio_put(folio);
> >                         ret++;
> >                 }
> > -               if (error == -ENOMEM)
> > +               if (error < 0)
> >                         break;
> >                 error = 0;
> >         }
> 
> Yes, this is the simplest and straightforward way to fix the issue. But it has the side effect
> that user will end up with a permanently mounted swap just because a sector is bad. That might
> be somewhat unacceptable?

Ah, you're right, swapoff should return with success instead of with
failure.  I tried the fix in your another email, and that makes swapoff
return with success, so your fix looks better than mine.

Thanks,
Naoya Horiguchi




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux