Re: Free a list_head

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi again :(

I'm facing with some problems with my list. I'll explain in detail:

I have a struct with fields that represent counters and also I have the list. These two elements are accessed from various points in my code:

The struct and the list are accessed from user context. The counters are incremented and a new element is added to the list. This is done only when a certain process is specified by the user. This code looks like this:

if (trace_enabled) { /*Checks if the current process is the user-specified one*/
                process_stats_inc_counter(&my_ps, 1);
                attach_to_list(1);
        }

Both functions does this work inside a critical section:

down_interruptible(&process_lock);
   /*Increment counters*/
up(&process_lock);

down_interruptible(&process_lock);
   /*Add element to list*/
up(&process_lock);

When adding the new element to the list, I check if the list is 200 elements long. If it is, I remove the "last" element. This is the only point where I remove an element from outside the clearing function.

When the user specifies the new pid I want to clear these data structures. The counters struct is cleared without problems, but I get an oops when trying to free the list:

down_interruptible(&process_lock);

/*Setting counters to 0
...
*/

list_for_each_entry_safe(p, my_node, &nodeList, list) {
                list_del(&my_node->list);
                kfree(my_node);
        }

        up(&process_lock);

If I comment this loop, the module doesn't crash so I think I'm doing (again...) something wrong with the list. This function is called from a procfs callback (where the user specifies the pid to trace).
list_for_each_entry_safe protects the list against removing, but no against adding, so I tried with the semaphore.

Any Ideas?

... my apologies for the length of the mail

On 7/11/06, Greg KH <greg@xxxxxxxxx> wrote:
On Tue, Jul 11, 2006 at 06:09:38PM +0200, Fernando Apestegu?a wrote:
> Hi,
>
> I would like to know how to free a list_head.
>
> I have almost 200 elements and I'm wonder if I must traverse the list for
> all the elements and do:
>
> list_for_each(...){
>   my_entry=list_entry(....)
>   list_del(my_entry)
>   kfree(my_entry)
> }
>
> Should I do this in this way?

No, try this instead:
        list_for_each_entry_safe(...) {
                list_del(my_entry);
                kfree(my_entry);
        }

The main point is the _safe usage if you are traversing a list and
deleting items from it at the same time.

Hope this helps,

greg k-h


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux