Re: Suspend 2 merge: 43/51: Utility functions.

Pavel Machek
2004-11-26T23:54:04Z

Hi!

> These are the routines that I think could possibly be useful elsewhere
> too.
>
> - A snprintf routine that returns the number of bytes actually put into
> the buffer, not the number that would have been put in if the buffer was
> big enough.
> - Routine for finding a proc dir entry (we use it to find /proc/splash
> when)
> - Support routines for dynamically allocated pageflags. Save those
> precious bits!

How many bits do you need? Two? I'd rather use thow two bits than have
yet another abstraction. Also note that it is doing big order
allocation.

Pavel
> +#define BITS_PER_PAGE (PAGE_SIZE * 8)
> +#define PAGES_PER_BITMAP ((max_mapnr + BITS_PER_PAGE - 1) / BITS_PER_PAGE)
> +#define BITMAP_ORDER (get_bitmask_order((PAGES_PER_BITMAP) - 1))
> +
> +/* clear_map
> + *
> + * Description: Clear an array used to store local page flags.
> + * Arguments: unsigned long *: The pagemap to be cleared.
> + */
> +
> +void clear_map(unsigned long * pagemap)
> +{
> + int size = (1 << BITMAP_ORDER) * PAGE_SIZE;
> +
> + memset(pagemap, 0, size);
> +}
> +
> +/* allocate_local_pageflags
> + *
> + * Description: Allocate a bitmap for local page flags.
> + * Arguments: unsigned long **: Pointer to the bitmap.
> + * int: Whether to set nosave flags for the
> + * newly allocated pages.
> + * Note: This looks suboptimal, but remember that we might be allocating
> + * the Nosave bitmap here.
> + */
> +int allocate_local_pageflags(unsigned long ** pagemap, int setnosave)
> +{
> + unsigned long * check;
> + int i;
> + if (*pagemap) {
> + printk("Error. Local pageflags map already allocated.\n");
> + clear_map(*pagemap);
> + } else {
> + check = (unsigned long *) __get_free_pages(GFP_ATOMIC,
> + BITMAP_ORDER);
> + if (!check) {
> + printk("Error. Unable to allocate memory for local page flags.");
> + return 1;
> + }
> + clear_map(check);
> + *pagemap = check;
> + if (setnosave) {
> + struct page * firstpage =
> + virt_to_page((unsigned long) check);
> + for (i = 0; i < (1 << BITMAP_ORDER); i++)
> + SetPageNosave(firstpage + i);
> + }
> + }
> + return 0;
> +}
> +
> +/* freemap
> + *
> + * Description: Free a local pageflags bitmap.
> + * Arguments: unsigned long **: Pointer to the bitmap being freed.
> + * Note: Map being freed might be Nosave.
> + */
> +int free_local_pageflags(unsigned long ** pagemap)
> +{
> + int i;
> + if (!*pagemap)
> + return 1;
> + else {
> + struct page * firstpage =
> + virt_to_page((unsigned long) *pagemap);
> + for (i = 0; i < (1 << BITMAP_ORDER); i++)
> + ClearPageNosave(firstpage + i);
> + free_pages((unsigned long) *pagemap, BITMAP_ORDER);
> + *pagemap = NULL;
> + return 0;
> + }
> +}
> +
> +EXPORT_SYMBOL(suspend_snprintf);
> +EXPORT_SYMBOL(allocate_local_pageflags);
> +EXPORT_SYMBOL(free_local_pageflags);
> +EXPORT_SYMBOL(find_proc_dir_entry);
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

--
People were complaining that M$ turns users into beta-testers...
...jr ghea gurz vagb qrirybcref, naq gurl frrz gb yvxr vg gung jnl!