MFC kern_linker.c 1.133 and related changes:
- push Giant into linker_reference_module(); - introduce linker_release_module(), which also takes care of proper locking. The latter also fixes a missing mtx_loc/unlock in subr_firmware.c . Apparently, digi.c is the only external client of linker_reference_module() which is a bit suspicious - perhaps dev/digi/ could make with a bit of review from someone knowledgeable to check how the function is used, and whether it could be replaced by something else.
This commit is contained in:
parent
1228e65f75
commit
d87a62d43f
@ -795,7 +795,7 @@ digi_loadmoduledata(struct digi_softc *sc)
|
||||
free(sym, M_TEMP);
|
||||
if (symptr == NULL) {
|
||||
printf("digi_%s.ko: Symbol `%s' not found\n", sc->module, sym);
|
||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
|
||||
linker_release_module(NULL, NULL, lf);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -803,7 +803,7 @@ digi_loadmoduledata(struct digi_softc *sc)
|
||||
if (digi_mod->dm_version != DIGI_MOD_VERSION) {
|
||||
printf("digi_%s.ko: Invalid version %d (need %d)\n",
|
||||
sc->module, digi_mod->dm_version, DIGI_MOD_VERSION);
|
||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
|
||||
linker_release_module(NULL, NULL, lf);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -825,7 +825,7 @@ digi_loadmoduledata(struct digi_softc *sc)
|
||||
bcopy(digi_mod->dm_link.data, sc->link.data, sc->link.size);
|
||||
}
|
||||
|
||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
|
||||
linker_release_module(NULL, NULL, lf);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -397,14 +397,44 @@ linker_reference_module(const char *modname, struct mod_depend *verinfo,
|
||||
linker_file_t *result)
|
||||
{
|
||||
modlist_t mod;
|
||||
int error;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
if ((mod = modlist_lookup2(modname, verinfo)) != NULL) {
|
||||
*result = mod->container;
|
||||
(*result)->refs++;
|
||||
mtx_unlock(&Giant);
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (linker_load_module(NULL, modname, NULL, verinfo, result));
|
||||
error = linker_load_module(NULL, modname, NULL, verinfo, result);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
linker_release_module(const char *modname, struct mod_depend *verinfo,
|
||||
linker_file_t lf)
|
||||
{
|
||||
modlist_t mod;
|
||||
int error;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
if (lf == NULL) {
|
||||
KASSERT(modname != NULL,
|
||||
("linker_release_module: no file or name"));
|
||||
mod = modlist_lookup2(modname, verinfo);
|
||||
if (mod == NULL) {
|
||||
mtx_unlock(&Giant);
|
||||
return (ESRCH);
|
||||
}
|
||||
lf = mod->container;
|
||||
} else
|
||||
KASSERT(modname == NULL && verinfo == NULL,
|
||||
("linker_release_module: both file and name"));
|
||||
error = linker_file_unload(lf, LINKER_UNLOAD_NORMAL);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
linker_file_t
|
||||
|
@ -197,9 +197,7 @@ firmware_get(const char *imagename)
|
||||
"load firmware image %s\n", __func__, imagename);
|
||||
return NULL;
|
||||
}
|
||||
mtx_lock(&Giant); /* XXX */
|
||||
(void) linker_reference_module(imagename, NULL, &result);
|
||||
mtx_unlock(&Giant); /* XXX */
|
||||
requested_load = 1;
|
||||
goto again; /* sort of an Algol-style for loop */
|
||||
}
|
||||
@ -218,7 +216,7 @@ unloadentry(void *unused1, int unused2)
|
||||
*/
|
||||
mtx_unlock(&firmware_mtx);
|
||||
|
||||
linker_file_unload(fp->file, LINKER_UNLOAD_NORMAL);
|
||||
linker_release_module(NULL, NULL, fp->file);
|
||||
|
||||
mtx_lock(&firmware_mtx);
|
||||
clearentry(fp, 0);
|
||||
|
@ -117,6 +117,14 @@ int linker_load_module(const char *_kldname, const char *_modname,
|
||||
int linker_reference_module(const char* _modname, struct mod_depend *_verinfo,
|
||||
linker_file_t* _result);
|
||||
|
||||
/*
|
||||
* Release a reference to a module, unloading it if there are no more
|
||||
* references. Note that one should either provide a module name and
|
||||
* optional version info or a linker file, but not both.
|
||||
*/
|
||||
int linker_release_module(const char *_modname, struct mod_depend *_verinfo,
|
||||
linker_file_t _file);
|
||||
|
||||
/*
|
||||
* Find a currently loaded file given its filename.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user