From 0f310a00e02094ea7a2a7d2ae45bd51d97706caa Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 8 Mar 2016 11:15:10 -0800 Subject: 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 Reviewed-by: Dean Luick Signed-off-by: Mitko Haralanov Signed-off-by: Jubin John Signed-off-by: Doug Ledford --- drivers/staging/rdma/hfi1/mmu_rb.c | 19 ++++++++++++++----- drivers/staging/rdma/hfi1/mmu_rb.h | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers/staging') 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 *); -- cgit v1.2.3-59-g8ed1b