Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu
[linux-2.6-microblaze.git] / include / rdma / ib_umem_odp.h
index 381cdf5..0b1446f 100644 (file)
@@ -43,6 +43,9 @@ struct umem_odp_node {
 };
 
 struct ib_umem_odp {
+       struct ib_umem umem;
+       struct ib_ucontext_per_mm *per_mm;
+
        /*
         * An array of the pages included in the on-demand paging umem.
         * Indices of pages that are currently not mapped into the device will
@@ -64,16 +67,9 @@ struct ib_umem_odp {
        struct mutex            umem_mutex;
        void                    *private; /* for the HW driver to use. */
 
-       /* When false, use the notifier counter in the ucontext struct. */
-       bool mn_counters_active;
        int notifiers_seq;
        int notifiers_count;
 
-       /* A linked list of umems that don't have private mmu notifier
-        * counters yet. */
-       struct list_head no_private_counters;
-       struct ib_umem          *umem;
-
        /* Tree tracking */
        struct umem_odp_node    interval_tree;
 
@@ -82,15 +78,34 @@ struct ib_umem_odp {
        struct work_struct      work;
 };
 
+static inline struct ib_umem_odp *to_ib_umem_odp(struct ib_umem *umem)
+{
+       return container_of(umem, struct ib_umem_odp, umem);
+}
+
 #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
 
-int ib_umem_odp_get(struct ib_ucontext *context, struct ib_umem *umem,
-                   int access);
-struct ib_umem *ib_alloc_odp_umem(struct ib_ucontext *context,
-                                 unsigned long addr,
-                                 size_t size);
+struct ib_ucontext_per_mm {
+       struct ib_ucontext *context;
+       struct mm_struct *mm;
+       struct pid *tgid;
+       bool active;
+
+       struct rb_root_cached umem_tree;
+       /* Protects umem_tree */
+       struct rw_semaphore umem_rwsem;
 
-void ib_umem_odp_release(struct ib_umem *umem);
+       struct mmu_notifier mn;
+       unsigned int odp_mrs_count;
+
+       struct list_head ucontext_list;
+       struct rcu_head rcu;
+};
+
+int ib_umem_odp_get(struct ib_umem_odp *umem_odp, int access);
+struct ib_umem_odp *ib_alloc_odp_umem(struct ib_ucontext_per_mm *per_mm,
+                                     unsigned long addr, size_t size);
+void ib_umem_odp_release(struct ib_umem_odp *umem_odp);
 
 /*
  * The lower 2 bits of the DMA address signal the R/W permissions for
@@ -105,13 +120,14 @@ void ib_umem_odp_release(struct ib_umem *umem);
 
 #define ODP_DMA_ADDR_MASK (~(ODP_READ_ALLOWED_BIT | ODP_WRITE_ALLOWED_BIT))
 
-int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 start_offset, u64 bcnt,
-                             u64 access_mask, unsigned long current_seq);
+int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 start_offset,
+                             u64 bcnt, u64 access_mask,
+                             unsigned long current_seq);
 
-void ib_umem_odp_unmap_dma_pages(struct ib_umem *umem, u64 start_offset,
+void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 start_offset,
                                 u64 bound);
 
-typedef int (*umem_call_back)(struct ib_umem *item, u64 start, u64 end,
+typedef int (*umem_call_back)(struct ib_umem_odp *item, u64 start, u64 end,
                              void *cookie);
 /*
  * Call the callback on each ib_umem in the range. Returns the logical or of
@@ -129,46 +145,37 @@ int rbt_ib_umem_for_each_in_range(struct rb_root_cached *root,
 struct ib_umem_odp *rbt_ib_umem_lookup(struct rb_root_cached *root,
                                       u64 addr, u64 length);
 
-static inline int ib_umem_mmu_notifier_retry(struct ib_umem *item,
+static inline int ib_umem_mmu_notifier_retry(struct ib_umem_odp *umem_odp,
                                             unsigned long mmu_seq)
 {
        /*
         * This code is strongly based on the KVM code from
         * mmu_notifier_retry. Should be called with
-        * the relevant locks taken (item->odp_data->umem_mutex
+        * the relevant locks taken (umem_odp->umem_mutex
         * and the ucontext umem_mutex semaphore locked for read).
         */
 
-       /* Do not allow page faults while the new ib_umem hasn't seen a state
-        * with zero notifiers yet, and doesn't have its own valid set of
-        * private counters. */
-       if (!item->odp_data->mn_counters_active)
-               return 1;
-
-       if (unlikely(item->odp_data->notifiers_count))
+       if (unlikely(umem_odp->notifiers_count))
                return 1;
-       if (item->odp_data->notifiers_seq != mmu_seq)
+       if (umem_odp->notifiers_seq != mmu_seq)
                return 1;
        return 0;
 }
 
 #else /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */
 
-static inline int ib_umem_odp_get(struct ib_ucontext *context,
-                                 struct ib_umem *umem,
-                                 int access)
+static inline int ib_umem_odp_get(struct ib_umem_odp *umem_odp, int access)
 {
        return -EINVAL;
 }
 
-static inline struct ib_umem *ib_alloc_odp_umem(struct ib_ucontext *context,
-                                               unsigned long addr,
-                                               size_t size)
+static inline struct ib_umem_odp *
+ib_alloc_odp_umem(struct ib_ucontext *context, unsigned long addr, size_t size)
 {
        return ERR_PTR(-EINVAL);
 }
 
-static inline void ib_umem_odp_release(struct ib_umem *umem) {}
+static inline void ib_umem_odp_release(struct ib_umem_odp *umem_odp) {}
 
 #endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */