diff options
| author | Thomas Zimmermann <tzimmermann@suse.de> | 2026-03-09 15:14:51 +0100 |
|---|---|---|
| committer | Helge Deller <deller@gmx.de> | 2026-03-09 15:47:21 +0100 |
| commit | 1de371b1f1b02dc82da598f9707089229699a604 (patch) | |
| tree | b64512a5f8d2601a23104e4f1251ed878ada78e5 /lib/fonts | |
| parent | e2e000a0b22036a72474088d3399097ff47ace02 (diff) | |
lib/fonts: Manage font-data lifetime with font_data_get/_put()
Add font_data_get() and font_data_put(). Update consoles to use them
over REFCOUNT() and plain kfree().
Newly allocated font data starts with a reference count of 1. Loading
the font puts the previously loaded font. If the reference count reaches
zero, font_data_put() frees the font data.
The kernel stores a refcount of zero for internal font data. Invoking
font_data_get() and font_data_put() tests this internally and returns
success without further operation. From the caller's perspective,
getting and putting works the same for all font data.
Fbcon used the userfont flag distinguish between internal fonts and
fonts loaded by user space. Only the latter where refcounted. With the
new helper's automatic handling of internal font data, remove the
userfont flag from fbcon.
Newport_con uses a default font, FONT_DATA, until user space loads
custom font data. Remove all special cases for FONT_DATA, as the get
and put calls' read-only handling also covers this case.
v3:
- fix module linker error wrt font symbols (Nathan, Arnd)
- fix typos
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'lib/fonts')
| -rw-r--r-- | lib/fonts/fonts.c | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/lib/fonts/fonts.c b/lib/fonts/fonts.c index 8c9a6762061c..d25efd8d6c31 100644 --- a/lib/fonts/fonts.c +++ b/lib/fonts/fonts.c @@ -12,18 +12,91 @@ * for more details. */ +#include <linux/container_of.h> +#include <linux/font.h> #include <linux/module.h> -#include <linux/types.h> +#include <linux/slab.h> #include <linux/string.h> +#include <linux/types.h> + #if defined(__mc68000__) #include <asm/setup.h> #endif -#include <linux/font.h> /* * Helpers for font_data_t */ +static struct font_data *to_font_data_struct(font_data_t *fd) +{ + return container_of(fd, struct font_data, data[0]); +} + +static bool font_data_is_internal(font_data_t *fd) +{ + return !REFCOUNT(fd); /* internal fonts have no reference counting */ +} + +static void font_data_free(font_data_t *fd) +{ + kfree(to_font_data_struct(fd)); +} + +/** + * font_data_get - Acquires a reference on font data + * @fd: Font data + * + * Font data from user space is reference counted. The helper + * font_data_get() increases the reference counter by one. Invoke + * font_data_put() to release the reference. + * + * Internal font data is located in read-only memory. In this case + * the helper returns success without modifying the counter field. + * It is still required to call font_data_put() on internal font data. + */ +void font_data_get(font_data_t *fd) +{ + if (font_data_is_internal(fd)) + return; /* never ref static data */ + + if (WARN_ON(!REFCOUNT(fd))) + return; /* should never be 0 */ + ++REFCOUNT(fd); +} +EXPORT_SYMBOL_GPL(font_data_get); + +/** + * font_data_put - Release a reference on font data + * @fd: Font data + * + * Font data from user space is reference counted. The helper + * font_data_put() decreases the reference counter by one. If this was + * the final reference, it frees the allocated memory. + * + * Internal font data is located in read-only memory. In this case + * the helper returns success without modifying the counter field. + * + * Returns: + * True if the font data's memory buffer has been freed, false otherwise. + */ +bool font_data_put(font_data_t *fd) +{ + unsigned int count; + + if (font_data_is_internal(fd)) + return false; /* never unref static data */ + + if (WARN_ON(!REFCOUNT(fd))) + return false; /* should never be 0 */ + + count = --REFCOUNT(fd); + if (!count) + font_data_free(fd); + + return !count; +} +EXPORT_SYMBOL_GPL(font_data_put); + /** * font_data_size - Return size of the font data in bytes * @fd: Font data |
