aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorMitko Haralanov <mitko.haralanov@intel.com>2016-03-08 11:15:10 -0800
committerDoug Ledford <dledford@redhat.com>2016-03-21 15:55:23 -0400
commit0f310a00e02094ea7a2a7d2ae45bd51d97706caa (patch)
treeb70733ef893c0725e6f1a1b8e2af85b6ba5e8705 /drivers/staging
parentIB/hfi1: Remove compare callback (diff)
downloadlinux-dev-0f310a00e02094ea7a2a7d2ae45bd51d97706caa.tar.xz
linux-dev-0f310a00e02094ea7a2a7d2ae45bd51d97706caa.zip
IB/hfi1: Add filter callback
This commit adds a filter callback, which can be used to filter out interval RB nodes matching a certain interval down to a single one. This is needed for the upcoming SDMA-side caching where buffers will need to be filtered by their virtual address. Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Reviewed-by: Dean Luick <dean.luick@intel.com> Signed-off-by: Mitko Haralanov <mitko.haralanov@intel.com> Signed-off-by: Jubin John <jubin.john@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/rdma/hfi1/mmu_rb.c19
-rw-r--r--drivers/staging/rdma/hfi1/mmu_rb.h1
2 files changed, 15 insertions, 5 deletions
diff --git a/drivers/staging/rdma/hfi1/mmu_rb.c b/drivers/staging/rdma/hfi1/mmu_rb.c
index 5d27fee577b9..6edd5f022057 100644
--- a/drivers/staging/rdma/hfi1/mmu_rb.c
+++ b/drivers/staging/rdma/hfi1/mmu_rb.c
@@ -181,13 +181,22 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler,
unsigned long addr,
unsigned long len)
{
- struct mmu_rb_node *node;
+ struct mmu_rb_node *node = NULL;
hfi1_cdbg(MMU, "Searching for addr 0x%llx, len %u", addr, len);
- node = __mmu_int_rb_iter_first(handler->root, addr, len);
- if (node)
- hfi1_cdbg(MMU, "Found node addr 0x%llx, len %u", node->addr,
- node->len);
+ if (!handler->ops->filter) {
+ node = __mmu_int_rb_iter_first(handler->root, addr,
+ (addr + len) - 1);
+ } else {
+ for (node = __mmu_int_rb_iter_first(handler->root, addr,
+ (addr + len) - 1);
+ node;
+ node = __mmu_int_rb_iter_next(node, addr,
+ (addr + len) - 1)) {
+ if (handler->ops->filter(node, addr, len))
+ return node;
+ }
+ }
return node;
}
diff --git a/drivers/staging/rdma/hfi1/mmu_rb.h b/drivers/staging/rdma/hfi1/mmu_rb.h
index 9c2600981e88..f8523fdb8a18 100644
--- a/drivers/staging/rdma/hfi1/mmu_rb.h
+++ b/drivers/staging/rdma/hfi1/mmu_rb.h
@@ -57,6 +57,7 @@ struct mmu_rb_node {
};
struct mmu_rb_ops {
+ bool (*filter)(struct mmu_rb_node *, unsigned long, unsigned long);
int (*insert)(struct rb_root *, struct mmu_rb_node *);
void (*remove)(struct rb_root *, struct mmu_rb_node *, bool);
int (*invalidate)(struct rb_root *, struct mmu_rb_node *);