On Thu, Jun 21, 2012 at 05:57:09PM -0400, Rik van Riel wrote: > + if (!vma->vm_prev) { > + /* This is the left-most VMA. */ > + if (vma->vm_start - len >= lower_limit) { > + addr = lower_limit; > + goto found_addr; > + } > + } else { > + /* Is this gap large enough? Remember it. */ > + vma_start = max(vma->vm_prev->vm_end, lower_limit); > + if (vma->vm_start - len >= vma_start) { > + addr = vma_start; > + found_here = true; > + } > + } You could unify these two cases: vma_start = lower_limit; if (vma->vm_prev && vma->vm_prev->vm_end > vma_start) vma_start = vma->vm_prev->vm_end; if (vma->vm_start - len >= vma_start) { addr = vma_start; found_here = true; } You don't need the goto found_addr; the search won't be going left as there is no node there and it won't be going right as found_here is true. We may also be albe to dispense with found_here and replace it with a special value (either NULL or something not page aligned) for addr. > + if (!found_here && node_free_gap(rb_node->rb_right) >= len) { > + /* Last known gap is to the right of this subtree. */ > + rb_node = rb_node->rb_right; > + continue; > + } else if (!addr) { > + rb_node = rb_find_next_uncle(rb_node); > + continue; > } Looks like you're already using my suggestion of using !addr to indicate we haven't found a suitable gap yet :) I don't think we want to visit just any uncle though - we want to visit one that has a large enough free gap somewhere in its subtree. So, maybe: if (!found_here) { // or if(!addr) or whatever struct rb_node *rb_prev = NULL; do { if (rb_node != rb_prev && node_free_gap(rb_node->rb_right) >= len) { rb_node = rb_node->rb_right; break; } rb_prev = rb_node; rb_node = rb_parent(rb_node); } while (rb_node); continue; } > + /* This is the left-most gap. */ > + goto found_addr; > } > + > + /* > + * There is not enough space to the left of any VMA. > + * Check the far right-hand side of the VMA tree. > + */ > + rb_node = mm->mm_rb.rb_node; > + while (rb_node->rb_right) > + rb_node = rb_node->rb_right; > + vma = rb_to_vma(rb_node); > + addr = vma->vm_end; > + > + /* > + * The right-most VMA ends below the lower limit. Can only happen > + * if a binary personality loads the stack below the executable. > + */ > + if (addr < lower_limit) > + addr = lower_limit; > + > + found_addr: > + if (TASK_SIZE - len < addr) > + return -ENOMEM; I'm confused - if we come from 'goto found_addr', we found a gap to the left of an existing vma; aren't we guaranteed that this gap ends to the left of TASK_SIZE too since the existing vma's vm_begin should be less than TASK_SIZE ? -- Michel "Walken" Lespinasse A program is never fully debugged until the last user dies. -- 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/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>