[Bug 260347] after kldunload memory allocated by the module stays wired

From: <bugzilla-noreply_at_freebsd.org>
Date: Sat, 11 Dec 2021 21:39:18 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=260347

            Bug ID: 260347
           Summary: after kldunload memory allocated by the module stays
                    wired
           Product: Base System
           Version: 13.0-RELEASE
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: martin@bxlr.sk

I have a very simple kernel module, textbook example, that uses static buffer.
It seems memory stays wired even if module is unloaded. If I do it enough times
system runs out of memory. Not reproducible on FreeBSD 12.2 amd64.

I'm opening the PR based on the forums discussion:
https://forums.freebsd.org/threads/kldunload-failed-to-release-memory.83286/

I don't agree with the replies there (mine are _martin); if I'm mistaken I
apologies for wasting everybody's time (and will rethink opening PR in the
future).

Simple kernel module:

/*
 * KLD Skeleton
 * Inspired by Andrew Reiter's Daemonnews article
 */

#include <sys/types.h>
#include <sys/module.h>
#include <sys/systm.h>  /* uprintf */
#include <sys/errno.h>
#include <sys/param.h>  /* defines used in kernel.h */
#include <sys/kernel.h> /* types used in module initialization */

#define BUFFER_SIZE 10*1000*1024 // 10 MB
static char gBuffer[BUFFER_SIZE];

static int demo_init (void)
{
  for (int i=0; i<BUFFER_SIZE; i++)
  {
    gBuffer[i] = 'A';
  }
  return 0;
}

static void demo_exit (void)
{
  for (int i=0; i<BUFFER_SIZE; i++)
  {
    gBuffer[i] += 1;
  }
}

/*
 * Load handler that deals with the loading and unloading of a KLD.
 */

static int
skel_loader(struct module *m, int what, void *arg)
{
  int err = 0;

  switch (what) {
  case MOD_LOAD:                /* kldload */
    uprintf("Skeleton KLD loaded.\n");
    demo_init();
    break;
  case MOD_UNLOAD:
    uprintf("Skeleton KLD unloaded.\n");
    demo_exit();
    break;
  default:
    err = EOPNOTSUPP;
    break;
  }
  return(err);
}

/* Declare this module to the rest of the kernel */

static moduledata_t skel_mod = {
  "skel",
  skel_loader,
  NULL
};

DECLARE_MODULE(skeleton, skel_mod, SI_SUB_KLD, SI_ORDER_ANY);

Makefile:

SRCS=skeleton.c
KMOD=skeleton

.include <bsd.kmod.mk>

I compile the module and test it with the loop:
sh
while true ; do kldload ./test.ko && kldunload ./test.ko ; done

In the other terminal I watch the memory utilization with top. Wired memory
increases to the point where system freezes. OOM killer kills processes and
system is available after a while. If I relaunch the top again I see wired
memory is still almost all used, as if module leaves memory leak. 

This behavior is not reproducible on FreeBSD 12.2 as I mentioned above.

-- 
You are receiving this mail because:
You are the assignee for the bug.