Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 91686
b: refs/heads/master
c: ddf0288
h: refs/heads/master
v: v3
  • Loading branch information
mark gross authored and Greg Kroah-Hartman committed Apr 21, 2008
1 parent 5eae11f commit 94a21ea
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c9e9e0bfc52ae93c246149c3b9d3a1e11677ca1a
refs/heads/master: ddf02886cbe665d67ca750750196ea5bf524b10b
50 changes: 36 additions & 14 deletions trunk/drivers/pci/iova.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,11 @@ iova_get_pad_size(int size, unsigned int limit_pfn)
return pad_size;
}

static int __alloc_iova_range(struct iova_domain *iovad, unsigned long size,
unsigned long limit_pfn, struct iova *new, bool size_aligned)
static int __alloc_and_insert_iova_range(struct iova_domain *iovad,
unsigned long size, unsigned long limit_pfn,
struct iova *new, bool size_aligned)
{
struct rb_node *curr = NULL;
struct rb_node *prev, *curr = NULL;
unsigned long flags;
unsigned long saved_pfn;
unsigned int pad_size = 0;
Expand All @@ -85,8 +86,10 @@ static int __alloc_iova_range(struct iova_domain *iovad, unsigned long size,
spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
saved_pfn = limit_pfn;
curr = __get_cached_rbnode(iovad, &limit_pfn);
prev = curr;
while (curr) {
struct iova *curr_iova = container_of(curr, struct iova, node);

if (limit_pfn < curr_iova->pfn_lo)
goto move_left;
else if (limit_pfn < curr_iova->pfn_hi)
Expand All @@ -100,6 +103,7 @@ static int __alloc_iova_range(struct iova_domain *iovad, unsigned long size,
adjust_limit_pfn:
limit_pfn = curr_iova->pfn_lo - 1;
move_left:
prev = curr;
curr = rb_prev(curr);
}

Expand All @@ -116,7 +120,33 @@ static int __alloc_iova_range(struct iova_domain *iovad, unsigned long size,
new->pfn_lo = limit_pfn - (size + pad_size) + 1;
new->pfn_hi = new->pfn_lo + size - 1;

/* Insert the new_iova into domain rbtree by holding writer lock */
/* Add new node and rebalance tree. */
{
struct rb_node **entry = &((prev)), *parent = NULL;
/* Figure out where to put new node */
while (*entry) {
struct iova *this = container_of(*entry,
struct iova, node);
parent = *entry;

if (new->pfn_lo < this->pfn_lo)
entry = &((*entry)->rb_left);
else if (new->pfn_lo > this->pfn_lo)
entry = &((*entry)->rb_right);
else
BUG(); /* this should not happen */
}

/* Add new node and rebalance tree. */
rb_link_node(&new->node, parent, entry);
rb_insert_color(&new->node, &iovad->rbroot);
}
__cached_rbnode_insert_update(iovad, saved_pfn, new);

spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);


return 0;
}

Expand Down Expand Up @@ -172,23 +202,15 @@ alloc_iova(struct iova_domain *iovad, unsigned long size,
size = __roundup_pow_of_two(size);

spin_lock_irqsave(&iovad->iova_alloc_lock, flags);
ret = __alloc_iova_range(iovad, size, limit_pfn, new_iova,
size_aligned);
ret = __alloc_and_insert_iova_range(iovad, size, limit_pfn,
new_iova, size_aligned);

spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
if (ret) {
spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
free_iova_mem(new_iova);
return NULL;
}

/* Insert the new_iova into domain rbtree by holding writer lock */
spin_lock(&iovad->iova_rbtree_lock);
iova_insert_rbtree(&iovad->rbroot, new_iova);
__cached_rbnode_insert_update(iovad, limit_pfn, new_iova);
spin_unlock(&iovad->iova_rbtree_lock);

spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);

return new_iova;
}

Expand Down

0 comments on commit 94a21ea

Please sign in to comment.