// Copyright 2021 The Fuchsia Authors
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <debug.h>
#include <inttypes.h>
#include <lib/arch/intrin.h>
#include <lib/console.h>
#include <lib/zircon-internal/macros.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <platform.h>
#include <stdio.h>
#include <string.h>

#include <fbl/algorithm.h>
#include <kernel/event.h>
#include <ktl/iterator.h>
#include <vm/loan_sweeper.h>
#include <vm/physical_page_borrowing_config.h>
#include <vm/pmm.h>

#include <ktl/enforce.h>

namespace {

// Singleton
static LoanSweeper loan_sweeper;
bool loan_sweeper_init_called = false;

}  // namespace

static int cmd_ppb(int argc, const cmd_args* argv, uint32_t flags);

STATIC_COMMAND_START
STATIC_COMMAND("ppb", "control contiguous physical page borrowing", &cmd_ppb)
STATIC_COMMAND_END(kernel)

DECLARE_SINGLETON_MUTEX(ppb_stats_lock);
static Thread* ppb_stats_thread TA_GUARDED(ppb_stats_lock::Get()) = nullptr;
static Event ppb_stats_thread_stop_event(false);

static void cmd_ppb_borrowing_on() {
  pmm_physical_page_borrowing_config()->set_borrowing_in_supplypages_enabled(true);
  pmm_physical_page_borrowing_config()->set_borrowing_on_mru_enabled(true);
  printf("borrowing enabled\n");
}

static void cmd_ppb_borrowing_off() {
  pmm_physical_page_borrowing_config()->set_borrowing_in_supplypages_enabled(false);
  pmm_physical_page_borrowing_config()->set_borrowing_on_mru_enabled(false);
  printf("borrowing disabled\n");
}

static void cmd_ppb_loaning_on() {
  pmm_physical_page_borrowing_config()->set_loaning_enabled(true);
  printf("loaning enabled\n");
}

static void cmd_ppb_loaning_off() {
  pmm_physical_page_borrowing_config()->set_loaning_enabled(false);
  printf("loaning disabled\n");
}

static void cmd_ppb_sweep() {
  if (!loan_sweeper_init_called) {
    loan_sweeper_init_called = true;
    loan_sweeper.Init();
  }
  uint64_t freed_page_count = loan_sweeper.ForceSynchronousSweep();
  printf("freed_page_count: %" PRIu64 " freed MiB: %" PRIu64 "\n", freed_page_count,
         freed_page_count * PAGE_SIZE / MB);
}

static void cmd_ppb_stats() { pmm_print_physical_page_borrowing_stats(); }

static void cmd_ppb_stats_on() {
  Thread* local_ppb_stats_thread;
  {  // scope guard
    Guard<Mutex> guard(ppb_stats_lock::Get());
    auto stats_thread = [](void* arg) -> int {
      while (true) {
        cmd_ppb_stats();
        zx_status_t status = ppb_stats_thread_stop_event.Wait(Deadline::after(ZX_SEC(1)));
        if (status == ZX_OK) {
          return 0;
        }
        DEBUG_ASSERT(status == ZX_ERR_TIMED_OUT);
      }
    };
    ppb_stats_thread = Thread::Create("ppb-stats-thread", stats_thread, nullptr, LOW_PRIORITY);
    ASSERT(ppb_stats_thread);
    local_ppb_stats_thread = ppb_stats_thread;
  }  // ~guard
  local_ppb_stats_thread->Resume();
}

static void cmd_ppb_stats_off() {
  Thread* local_ppb_stats_thread;
  {  // scope guard
    Guard<Mutex> guard(ppb_stats_lock::Get());
    local_ppb_stats_thread = ppb_stats_thread;
    ppb_stats_thread = nullptr;
  }  // ~guard
  ppb_stats_thread_stop_event.Signal();
  int retcode;
  local_ppb_stats_thread->Join(&retcode, ZX_TIME_INFINITE);
  DEBUG_ASSERT(!retcode);
  ppb_stats_thread_stop_event.Unsignal();
}

using CmdFunc = void (*)();
struct Cmd {
  const char* name;
  CmdFunc func;
};

static Cmd commands[] = {
    {"borrowing_on", cmd_ppb_borrowing_on},
    {"borrowing_off", cmd_ppb_borrowing_off},
    {"loaning_on", cmd_ppb_loaning_on},
    {"loaning_off", cmd_ppb_loaning_off},
    {"sweep", cmd_ppb_sweep},
    {"stats", cmd_ppb_stats},
    {"stats_on", cmd_ppb_stats_on},
    {"stats_off", cmd_ppb_stats_off},
};

// k ppb borrowing_on
//   * this is the default on boot
//   * enables page borrowing for new allocations (does not sweep)
//   * see also k ppb borrowing_off
// k ppb borrowing_off
//   * disables page borrowing for new allocations (does not sweep)
//   * see also k ppb borrowing_on
// k ppb loaning_on
//   * enables loaning when a contiguous VMO pages are decommitted
// k ppb loaning_off
//   * disables loaning when a contiguous VMO pages are decommitted
// k ppb sweep
//   * If ppb is on, borrows as many pages as possible in a single sweep
//   * If ppb is off, un-borrows all borrowed pages (may cause OOM, depending)
//   * The sweep also respects non_pager_on / non_pager_off, etc
// k ppb stats
//   * output ppb-related stats (once)
// k ppb stats_on
//   * repeatedly output ppb-relevant stats (fairly frequently, for observing usage scenarios)
// k ppb stats_off
//   * stop repeatedly outputting ppb-relevant stats
static int cmd_ppb(int argc, const cmd_args* argv, uint32_t flags) {
  if (argc != 2) {
    printf("2 arguments expected\n");
    printf("usage:\n");
    printf("ppb <cmd>\n");
    printf("command list:\n");
    for (auto& cmd : commands) {
      printf("%s\n", cmd.name);
    }
    return -1;
  }

  for (auto& cmd : commands) {
    if (!strcmp(argv[1].str, cmd.name)) {
      cmd.func();
      return 0;
    }
  }
  printf("sub-command not found - available sub-commands:\n");
  for (auto& cmd : commands) {
    printf("%s\n", cmd.name);
  }
  return -1;
}
