Updated micscif/micscif_rma.c to address changes in callback functions stored in...
authorAaron Taylor <ataylor@subgeniuskitty.com>
Wed, 5 May 2021 23:11:24 +0000 (16:11 -0700)
committerAaron Taylor <ataylor@subgeniuskitty.com>
Wed, 5 May 2021 23:11:24 +0000 (16:11 -0700)
micscif/micscif_rma.c

index 870746c..32f8adb 100644 (file)
@@ -57,12 +57,10 @@ void micscif_rma_destroy_tcw(struct rma_mmu_notifier *mmn,
 #ifdef CONFIG_MMU_NOTIFIER
 static void scif_mmu_notifier_release(struct mmu_notifier *mn,
                        struct mm_struct *mm);
 #ifdef CONFIG_MMU_NOTIFIER
 static void scif_mmu_notifier_release(struct mmu_notifier *mn,
                        struct mm_struct *mm);
-static void scif_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
-                               struct mm_struct *mm,
-                               unsigned long address);
-static void scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
+static int scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
                                       struct mm_struct *mm,
                                       struct mm_struct *mm,
-                                      unsigned long start, unsigned long end);
+                                      unsigned long start, unsigned long end,
+                                      bool blockable);
 static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
                                     struct mm_struct *mm,
                                     unsigned long start, unsigned long end);
 static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
                                     struct mm_struct *mm,
                                     unsigned long start, unsigned long end);
@@ -70,7 +68,6 @@ static const struct mmu_notifier_ops scif_mmu_notifier_ops = {
        .release = scif_mmu_notifier_release,
        .clear_flush_young = NULL,
        .change_pte = NULL,/*TODO*/
        .release = scif_mmu_notifier_release,
        .clear_flush_young = NULL,
        .change_pte = NULL,/*TODO*/
-       .invalidate_page = scif_mmu_notifier_invalidate_page,
        .invalidate_range_start = scif_mmu_notifier_invalidate_range_start,
        .invalidate_range_end = scif_mmu_notifier_invalidate_range_end};
 
        .invalidate_range_start = scif_mmu_notifier_invalidate_range_start,
        .invalidate_range_end = scif_mmu_notifier_invalidate_range_end};
 
@@ -86,30 +83,40 @@ static void scif_mmu_notifier_release(struct mmu_notifier *mn,
        return;
 }
 
        return;
 }
 
-static void scif_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
-                               struct mm_struct *mm,
-                               unsigned long address)
-{
-       struct endpt *ep;
-       struct rma_mmu_notifier *mmn;
-       mmn = container_of(mn, struct rma_mmu_notifier, ep_mmu_notifier);
-       ep = mmn->ep;
-       micscif_rma_destroy_tcw(mmn, ep, true, address, PAGE_SIZE);
-       pr_debug("%s address 0x%lx\n", __func__, address);
-       return;
-}
-
-static void scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
+static int scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
                                       struct mm_struct *mm,
                                       struct mm_struct *mm,
-                                      unsigned long start, unsigned long end)
+                                      unsigned long start, unsigned long end,
+                                      bool blockable)
 {
        struct endpt *ep;
        struct rma_mmu_notifier *mmn;
        mmn = container_of(mn, struct rma_mmu_notifier, ep_mmu_notifier);
        ep = mmn->ep;
 {
        struct endpt *ep;
        struct rma_mmu_notifier *mmn;
        mmn = container_of(mn, struct rma_mmu_notifier, ep_mmu_notifier);
        ep = mmn->ep;
+       /*
+        * The kernel file `include/linux/mmu_notifier.h` states the following
+        * regarding the invalidate_range_start() callback:
+        *
+        *     If blockable argument is set to false then the callback cannot
+        *     sleep and has to return with -EAGAIN. 0 should be returned
+        *     otherwise.
+        *
+        * The following function executes spin_lock_irqsave(), which feels like it
+        * qualifies as 'sleep'. However, returning -EAGAIN would require me to
+        * understand the location and function of all code that calls this
+        * callback. I do not yet have that understanding.
+        *
+        * For now, maintain the original behavior of calling
+        * micscif_rma_destroy_tcw() every time, accepting the spinlock. If this
+        * becomes problematic, either figure out all the code that can call this
+        * function and teach it to understand -EAGAIN, or investigate the `#ifdef
+        * CONFIG_MMU_NOTIFIER`.
+        *
+        * If you ended up here while tracking down a bug and pulling your hair
+        * out, sorry. :-(
+        */
        micscif_rma_destroy_tcw(mmn, ep, true, (uint64_t)start, (uint64_t)(end - start));
        pr_debug("%s start=%lx, end=%lx\n", __func__, start, end);
        micscif_rma_destroy_tcw(mmn, ep, true, (uint64_t)start, (uint64_t)(end - start));
        pr_debug("%s start=%lx, end=%lx\n", __func__, start, end);
-       return;
+       return 0;
 }
 
 static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
 }
 
 static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,