Skip to content

Commit

Permalink
use THIS_MODULE instead of the provider's name
Browse files Browse the repository at this point in the history
more context is available
also incrementing provider module's refcount to prevent unloading when in use
  • Loading branch information
calccrypto committed Jul 1, 2024
1 parent d8e4511 commit 4644789
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 42 deletions.
4 changes: 2 additions & 2 deletions examples/providers/bsd/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

static int __init
dpusm_bsd_provider_init(void) {
const int rc = dpusm_register_bsd(module_name(THIS_MODULE),
const int rc = dpusm_register_bsd(THIS_MODULE,
&example_dpusm_provider_functions);
printk("%s init: %d\n", module_name(THIS_MODULE), rc);
return rc;
}

static void __exit
dpusm_bsd_provider_exit(void) {
dpusm_unregister_bsd(module_name(THIS_MODULE));
dpusm_unregister_bsd(THIS_MODULE);

printk("%s exit\n", module_name(THIS_MODULE));
}
Expand Down
4 changes: 2 additions & 2 deletions examples/providers/gpl/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

static int __init
dpusm_gpl_provider_init(void) {
const int rc = dpusm_register_gpl(module_name(THIS_MODULE),
const int rc = dpusm_register_gpl(THIS_MODULE,
&example_dpusm_provider_functions);
printk("%s init: %d\n", module_name(THIS_MODULE), rc);
return rc;
}

static void __exit
dpusm_gpl_provider_exit(void) {
dpusm_unregister_gpl(module_name(THIS_MODULE));
dpusm_unregister_gpl(THIS_MODULE);

printk("%s exit\n", module_name(THIS_MODULE));
}
Expand Down
7 changes: 4 additions & 3 deletions include/dpusm/provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

#include <linux/atomic.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/spinlock.h>

#include <dpusm/provider_api.h>

/* single provider data */
typedef struct dpusm_provider_handle {
const char *name; /* reference to a string */
struct module *module;
dpusm_pc_t capabilities; /* constant set of capabilities */
const dpusm_pf_t *funcs; /* reference to a struct */
atomic_t refs; /* how many users are holding this provider */
Expand All @@ -25,11 +26,11 @@ typedef struct {
/* this is not tied to the provider/count */
} dpusm_t;

int dpusm_provider_register(dpusm_t *dpusm, const char *name, const dpusm_pf_t *funcs);
int dpusm_provider_register(dpusm_t *dpusm, struct module *module, const dpusm_pf_t *funcs);

/* can't prevent provider module from unloading */
int dpusm_provider_unregister_handle(dpusm_t *dpusm, dpusm_ph_t **provider);
int dpusm_provider_unregister(dpusm_t *dpusm, const char *name);
int dpusm_provider_unregister(dpusm_t *dpusm, struct module *module);

dpusm_ph_t **dpusm_provider_get(dpusm_t *dpusm, const char *name);
int dpusm_provider_put(dpusm_t *dpusm, void *handle);
Expand Down
8 changes: 4 additions & 4 deletions include/dpusm/provider_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,10 @@ typedef struct dpusm_provider_functions {
} dpusm_pf_t;

/* returns -ERRNO instead of DPUSM_* */
int dpusm_register_bsd(const char *name, const dpusm_pf_t *funcs);
int dpusm_unregister_bsd(const char *name);
int dpusm_register_gpl(const char *name, const dpusm_pf_t *funcs);
int dpusm_unregister_gpl(const char *name);
int dpusm_register_bsd(struct module *module, const dpusm_pf_t *funcs);
int dpusm_unregister_bsd(struct module *module);
int dpusm_register_gpl(struct module *module, const dpusm_pf_t *funcs);
int dpusm_unregister_gpl(struct module *module);

/*
* call when backing DPU goes down unexpectedly
Expand Down
19 changes: 9 additions & 10 deletions src/dpusm.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,27 @@
static dpusm_t dpusm;

int
dpusm_register_bsd(const char *name, const dpusm_pf_t *funcs) {
return dpusm_provider_register(&dpusm, name, funcs);
dpusm_register_bsd(struct module *module, const dpusm_pf_t *funcs) {
return dpusm_provider_register(&dpusm, module, funcs);
}

int
dpusm_unregister_bsd(const char *name) {
return dpusm_provider_unregister(&dpusm, name);
dpusm_unregister_bsd(struct module *module) {
return dpusm_provider_unregister(&dpusm, module);
}

/* provider facing functions */
EXPORT_SYMBOL(dpusm_register_bsd);
EXPORT_SYMBOL(dpusm_unregister_bsd);

int
dpusm_register_gpl(const char *name, const dpusm_pf_t *funcs) {
return dpusm_provider_register(&dpusm, name, funcs);
dpusm_register_gpl(struct module *module, const dpusm_pf_t *funcs) {
return dpusm_provider_register(&dpusm, module, funcs);
}

int
dpusm_unregister_gpl(const char *name) {
return dpusm_provider_unregister(&dpusm, name);
dpusm_unregister_gpl(struct module *module) {
return dpusm_provider_unregister(&dpusm, module);
}

/* provider facing functions */
Expand Down Expand Up @@ -76,8 +76,7 @@ dpusm_init(void) {
}

static void __exit
dpusm_exit(void)
{
dpusm_exit(void) {
dpusm_provider_write_lock(&dpusm);

const int active = atomic_read(&dpusm.active);
Expand Down
48 changes: 29 additions & 19 deletions src/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ find_provider(dpusm_t *dpusm, const char *name) {
struct list_head *it = NULL;
list_for_each(it, &dpusm->providers) {
dpusm_ph_t *dpusmph = list_entry(it, dpusm_ph_t, list);
const char *p_name = dpusmph->name;
const char *p_name = module_name(dpusmph->module);
const size_t p_name_len = strlen(p_name);
if (name_len == p_name_len) {
if (memcmp(name, p_name, p_name_len) == 0) {
Expand All @@ -108,8 +108,9 @@ static void print_supported(const char *name, const char *func)
}

static dpusm_ph_t *
dpusmph_init(const char *name, const dpusm_pf_t *funcs)
dpusmph_init(struct module *module, const dpusm_pf_t *funcs)
{
const char *name = module_name(module);
dpusm_ph_t *dpusmph = dpusm_mem_alloc(sizeof(dpusm_ph_t));
if (dpusmph) {
/* fill in capabilities bitmasks */
Expand Down Expand Up @@ -223,7 +224,7 @@ dpusmph_init(const char *name, const dpusm_pf_t *funcs)
dpusmph->capabilities.io &= ~DPUSM_IO_DISK;
}

dpusmph->name = name;
dpusmph->module = module;
dpusmph->funcs = funcs;
dpusmph->self = dpusmph;
atomic_set(&dpusmph->refs, 0);
Expand All @@ -234,7 +235,7 @@ dpusmph_init(const char *name, const dpusm_pf_t *funcs)

/* add a new provider */
int
dpusm_provider_register(dpusm_t *dpusm, const char *name, const dpusm_pf_t *funcs) {
dpusm_provider_register(dpusm_t *dpusm, struct module *module, const dpusm_pf_t *funcs) {
const int rc = dpusm_provider_sane_at_load(funcs);
if (rc != DPUSM_OK) {
static const size_t max =
Expand All @@ -258,7 +259,7 @@ dpusm_provider_register(dpusm_t *dpusm, const char *name, const dpusm_pf_t *func

printk("%s: DPUSM Provider \"%s\" does not provide "
"a valid set of functions. Bad function groups: %s\n",
__func__, name, buf);
__func__, module_name(module), buf);

dpusm_mem_free(buf, size);

Expand All @@ -267,15 +268,15 @@ dpusm_provider_register(dpusm_t *dpusm, const char *name, const dpusm_pf_t *func

dpusm_provider_write_lock(dpusm);

dpusm_ph_t **found = find_provider(dpusm, name);
dpusm_ph_t **found = find_provider(dpusm, module_name(module));
if (found) {
printk("%s: DPUSM Provider with the name \"%s\" (%p) already exists. %zu providers registered.\n",
__func__, name, *found, dpusm->count);
__func__, module_name(module), *found, dpusm->count);
dpusm_provider_write_unlock(dpusm);
return -EEXIST;
}

dpusm_ph_t *provider = dpusmph_init(name, funcs);
dpusm_ph_t *provider = dpusmph_init(module, funcs);
if (!provider) {
dpusm_provider_write_unlock(dpusm);
return -ECANCELED;
Expand All @@ -284,16 +285,14 @@ dpusm_provider_register(dpusm_t *dpusm, const char *name, const dpusm_pf_t *func
list_add(&provider->list, &dpusm->providers);
dpusm->count++;
printk("%s: DPUSM Provider \"%s\" (%p) added. Now %zu providers registered.\n",
__func__, name, provider, dpusm->count);
__func__, module_name(module), provider, dpusm->count);

dpusm_provider_write_unlock(dpusm);

return 0;
}

/* remove provider from list */
/* can't prevent provider module from unloading */
/* locking is done by caller */
int
dpusm_provider_unregister_handle(dpusm_t *dpusm, dpusm_ph_t **provider) {
if (!provider || !*provider) {
Expand All @@ -305,7 +304,7 @@ dpusm_provider_unregister_handle(dpusm_t *dpusm, dpusm_ph_t **provider) {
const int refs = atomic_read(&(*provider)->refs);
if (refs) {
printk("%s: Unregistering provider \"%s\" with %d references remaining.\n",
__func__, (*provider)->name, refs);
__func__, module_name((*provider)->module), refs);
rc = -EBUSY;
}

Expand All @@ -321,19 +320,19 @@ dpusm_provider_unregister_handle(dpusm_t *dpusm, dpusm_ph_t **provider) {
}

int
dpusm_provider_unregister(dpusm_t *dpusm, const char *name) {
dpusm_provider_unregister(dpusm_t *dpusm, struct module *module) {
dpusm_provider_write_lock(dpusm);

dpusm_ph_t **provider = find_provider(dpusm, name);
dpusm_ph_t **provider = find_provider(dpusm, module_name(module));
if (!provider) {
printk("%s: Could not find provider with name \"%s\"\n", __func__, name);
printk("%s: Could not find provider with name \"%s\"\n", __func__, module_name(module));
dpusm_provider_write_unlock(dpusm);
return DPUSM_ERROR;
}

void *addr = *provider;
const int rc = dpusm_provider_unregister_handle(dpusm, provider);
printk("%s: Unregistered \"%s\" (%p): %d\n", __func__, name, addr, rc);
printk("%s: Unregistered \"%s\" (%p): %d\n", __func__, module_name(module), addr, rc);

dpusm_provider_write_unlock(dpusm);
return rc;
Expand All @@ -350,10 +349,17 @@ dpusm_provider_get(dpusm_t *dpusm, const char *name) {
read_lock(&dpusm->lock);
dpusm_ph_t **provider = find_provider(dpusm, name);
if (provider) {
/* make sure provider can't be unloaded before user */
if (!try_module_get((*provider)->module)) {
printk("Error: Could not increment reference count of %s\n", name);
return NULL;
}

atomic_inc(&(*provider)->refs);
atomic_inc(&dpusm->active);

printk("%s: User has been given a handle to \"%s\" (%p) (now %d users).\n",
__func__, (*provider)->name, *provider, atomic_read(&(*provider)->refs));
__func__, name, *provider, atomic_read(&(*provider)->refs));

if ((*provider)->funcs->at_connect) {
(*provider)->funcs->at_connect();
Expand All @@ -376,12 +382,15 @@ dpusm_provider_put(dpusm_t *dpusm, void *handle) {
return DPUSM_ERROR;
}

struct module *module = (*provider)->module;

if (!atomic_read(&(*provider)->refs)) {
printk("%s Error: Cannot decrement provider \"%s\" user count already at 0.\n",
__func__, (*provider)->name);
__func__, module_name(module));
return DPUSM_ERROR;
}

module_put(module);
atomic_dec(&(*provider)->refs);
atomic_dec(&dpusm->active);

Expand All @@ -392,7 +401,7 @@ dpusm_provider_put(dpusm_t *dpusm, void *handle) {
}

printk("%s: User has returned a handle to \"%s\" (%p) (now %d users).\n",
__func__, (*provider)->name, *provider, atomic_read(&(*provider)->refs));
__func__, module_name(module), *provider, atomic_read(&(*provider)->refs));
return DPUSM_OK;
}

Expand All @@ -414,6 +423,7 @@ void dpusm_provider_invalidate(dpusm_t *dpusm, const char *name) {
memset(&(*provider)->capabilities, 0, sizeof((*provider)->capabilities));
printk("%s: Provider \"%s\" has been invalidated with %d users active.\n",
__func__, name, atomic_read(&(*provider)->refs));
/* not decrementing module reference count here - provider is still registered */
}
else {
printk("%s: Error: Did not find provider \"%s\"\n",
Expand Down
4 changes: 2 additions & 2 deletions src/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ dpusm_provider_sane(dpusm_ph_t **provider) {
}

if (!FUNCS(provider)) {
printk("Error: Invalidated provider: %s\n", (*provider)->name);
printk("Error: Invalidated provider: %s\n", module_name((*provider)->module));
return DPUSM_PROVIDER_INVALIDATED;
}

Expand Down Expand Up @@ -144,7 +144,7 @@ dpusm_get_provider(const char *name) {
static const char *
dpusm_get_provider_name(void *provider) {
dpusm_ph_t **dpusmph = (dpusm_ph_t **) provider;
return (dpusmph && *dpusmph)?(*dpusmph)->name:NULL;
return (dpusmph && *dpusmph)?module_name((*dpusmph)->module):NULL;
}

static int
Expand Down

0 comments on commit 4644789

Please sign in to comment.