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

William Lee Irwin III (wli@holomorphy.com)
Mon, 27 May 2002 12:40:18 -0700


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/