Be careful not to unconditionally clear the PF_MEMALLOC bit in
the task structure. It may have already been set when entering
zpl_putpage() in which case it must remain set on exit. In
particular the kswapd thread will have PF_MEMALLOC set in
order to prevent it from entering direct reclaim. By clearing
it we allow the following NULL deref to potentially occur.
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<
ffffffff8109c7ab>] balance_pgdat+0x25b/0x4ff
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #287
* the VM might try to write out additional pages by calling
* zpl_putpage() again resulting in a deadlock.
*/
- current->flags |= PF_MEMALLOC;
- (void) zfs_putpage(mapping->host, pp, wbc);
- current->flags &= ~PF_MEMALLOC;
+ if (current->flags & PF_MEMALLOC) {
+ (void) zfs_putpage(mapping->host, pp, wbc);
+ } else {
+ current->flags |= PF_MEMALLOC;
+ (void) zfs_putpage(mapping->host, pp, wbc);
+ current->flags &= ~PF_MEMALLOC;
+ }
return (0);
}