Re: suspend-to-{RAM,disk} for 2.5.17

From: William Lee Irwin III (wli@holomorphy.com)
Date: Mon May 27 2002 - 14:40:18 EST


On Wed, May 22, 2002 at 12:28:59AM +0200, Pavel Machek wrote:
...

I foresee trouble here; you're doing list_entry(list, struct page, list)
on &area->free_list.

On Wed, May 22, 2002 at 12:28:59AM +0200, Pavel Machek wrote:
> +#ifdef CONFIG_SOFTWARE_SUSPEND
> +int is_head_of_free_region(struct page *p)
> +{
> + pg_data_t *pgdat = pgdat_list;
> + unsigned type;
> + unsigned long flags;
> +
> + for (type=0;type < MAX_NR_ZONES; type++) {
> + zone_t *zone = pgdat->node_zones + type;
> + int order = MAX_ORDER - 1;
> + free_area_t *area;
> + struct list_head *head, *curr;
> + spin_lock_irqsave(&zone->lock, flags); /* Should not matter as we need quiescent system for suspend anyway, but... */
> +
> + do {
> + area = zone->free_area + order;
> + head = &area->free_list;
> + curr = head;

                        ^^^^^^^^^^^^
                        set right here

On Wed, May 22, 2002 at 12:28:59AM +0200, Pavel Machek wrote:
> +
> + for(;;) {
> + if(!curr) {
> +// printk("FIXME: this should not happen but it does!!!");
> + break;
> + }
> + if(p != memlist_entry(curr, struct page, list)) {
> + curr = memlist_next(curr);
> + if (curr == head)
> + break;
> + continue;
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       deep trouble here and in the if ()

On Wed, May 22, 2002 at 12:28:59AM +0200, Pavel Machek wrote:
> + }
> + return 1 << order;
> + }
> + } while(order--);
> + spin_unlock_irqrestore(&zone->lock, flags);
> +
> + }
> + return 0;
> +}
> +#endif /* CONFIG_SOFTWARE_SUSPEND */

The rest is okay...

I'd try writing it this way, and though I've not tested it, I've walked
buddy lists a few times in the past week or two:

#ifdef CONFIG_SOFTWARE_SUSPEND
int is_head_of_free_region(struct page *page)
{
        zone_t *zone, *node_zones = pgdat_list->node_zones;
        unsigned long flags;

        for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
                int order;
                list_t *curr;

                /*
                 * Should not matter as we need quiescent system for
                 * suspend anyway, but...
                 */
                spin_lock_irqsave(&zone->lock, flags);
                for (order = MAX_ORDER - 1; order >= 0; --order)
                        list_for_each(curr, &zone->free_area[order].free_list)
                                if (page == list_entry(curr, struct page, list))
                                        return 1 << order;
                spin_unlock_irqrestore(&zone->lock, flags);

        }
        return 0;
}
#endif /* CONFIG_SOFTWARE_SUSPEND */

Cheers,
Bill
-
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/



This archive was generated by hypermail 2b29 : Fri May 31 2002 - 22:00:21 EST