On Fri, 2007-03-09 at 10:15 +0200, Pekka J Enberg wrote: > +static int revoke_vma(struct vm_area_struct *vma, struct zap_details > *details) > +{ > + unsigned long restart_addr, start_addr, end_addr; > + int need_break; > + > + start_addr = vma->vm_start; > + end_addr = vma->vm_end; > + > + /* > + * Not holding ->mmap_sem here. > + */ > + vma->vm_flags |= VM_REVOKED; > + smp_mb();
Hmm, i_mmap_lock pins the vma and excludes modifications, but doesn't exclude concurrent faults. I guess its save. > + again: > + restart_addr = zap_page_range(vma, start_addr, end_addr - start_addr, > + details); > + > + need_break = need_resched() || need_lockbreak(details->i_mmap_lock); > + if (need_break) > + goto out_need_break; > + > + if (restart_addr < end_addr) { > + start_addr = restart_addr; > + goto again; > + } > + return 0; > + > + out_need_break: > + spin_unlock(details->i_mmap_lock); > + cond_resched(); > + spin_lock(details->i_mmap_lock); > + return -EINTR; I'm not sure this scheme works, given a sufficiently loaded machine, this might never complete. > +} > + > +static int revoke_mapping(struct address_space *mapping, struct file > *to_exclude) > +{ > + struct vm_area_struct *vma; > + struct prio_tree_iter iter; > + struct zap_details details; > + int err = 0; > + > + details.i_mmap_lock = &mapping->i_mmap_lock; > + > + spin_lock(&mapping->i_mmap_lock); > + vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, 0, ULONG_MAX) { > + if (vma->vm_flags & VM_SHARED && vma->vm_file != to_exclude) { I'm never sure of operator precedence and prefer: (vma->vm_flags & VM_SHARED) && ... which leaves no room for error. > + err = revoke_vma(vma, &details); > + if (err) > + goto out; > + } > + } > + > + list_for_each_entry(vma, &mapping->i_mmap_nonlinear, > shared.vm_set.list) { > + if (vma->vm_flags & VM_SHARED && vma->vm_file != to_exclude) { Idem. > + err = revoke_vma(vma, &details); > + if (err) > + goto out; > + } > + } > + out: > + spin_unlock(&mapping->i_mmap_lock); > + return err; > +} - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/