On Fri, 2011-06-17 at 14:35 +0530, Srikar Dronamraju wrote: > > > > int mmap_uprobe(...) > > > > { > > > > spin_lock(&uprobes_treelock); > > > > for_each_probe_in_inode() { > > > > // create list; > > Here again if we have multiple mmaps for the same inode occuring on two > process contexts (I mean two different mm's), we have to manage how we > add the same uprobe to more than one list. Atleast my current > uprobe->pending_list wouldnt work. Sure, wasn't concerned about that particular problem. > > > > } > > > > spin_unlock(..); > > > > > > > > list_for_each_entry_safe() { > > > > // remove from list > > > > ret = install_breakpoint(); > > > > if (ret) > > > > goto fail; > > > > if (!uprobe_still_there()) // takes treelock > > > > remove_breakpoint(); > > > > } > > > > > > > > return 0; > > > > > > > > fail: > > > > list_for_each_entry_safe() { > > > > // destroy list > > > > } > > > > return ret; > > > > } > > > > > > > > > > > > > register_uprobe will race with mmap_uprobe's first pass. > > > So we might end up with a vma that doesnot have a breakpoint inserted > > > but inserted in all other vma that map to the same inode. > > > > I'm not seeing this though, if mmap_uprobe() is before register_uprobe() > > inserts the probe in the tree, the vma is already in the rmap and > > register_uprobe() will find it in its vma walk. If its after, > > mmap_uprobe() will find it and install, if a concurrent > > register_uprobe()'s vma walk also finds it, it will -EEXISTS and ignore > > the error. > > > > You are right here. > > What happens if the register_uprobe comes first and walks around the > vmas, Between mmap comes in does the insertion including the second pass > and returns. register_uprobe now finds that it cannot insert breakpoint > on one of the vmas and hence has to roll-back. The vma on which > mmap_uprobe inserted will not be in the list of vmas from which we try > to remove the breakpoint. Yes it will, remember __register_uprobe() will call __unregister_uprobe() on fail, which does a new vma-rmap walk which will then see the newly added mmap. > How about something like this: > if (!mutex_trylock(uprobes_mutex)) { > > /* > * Unable to get uprobes_mutex; Probably contending with > * someother thread. Drop mmap_sem; acquire uprobes_mutex > * and mmap_sem and then verify vma. > */ > > up_write(&mm->mmap_sem); > mutex_lock&(uprobes_mutex); > down_write(&mm->mmap_sem); > vma = find_vma(mm, start); > /* Not the same vma */ > if (!vma || vma->vm_start != start || > vma->vm_pgoff != pgoff || !valid_vma(vma) || > inode->i_mapping != vma->vm_file->f_mapping) > goto mmap_out; > } Only if we have to, I really don't like dropping mmap_sem in the middle of mmap. I'm fairly sure we can come up with some ordering scheme that ought to make mmap_uprobe() work without the uprobes_mutex. On thing I was thinking of to fix that initial problem of spurious traps was to leave the uprobe in the tree but skip all probes without consumers in mmap_uprobe(). -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href