On Fri, Aug 05, 2005 at 11:37:33 +0000, Vincenzo Mallozzi wrote: > On Thu 5 Aug 2005, at 07:02, Jan Hudec wrote: > > Perhaps your code is safe, but I would think you should have the list > > modification itself (list_add_tail) protected by a spin_lock_irqsave. > > That's the only way to exclude against interrupts (you can't lock > > semaphores in interrupt context). > > > > But I'm developing a project in a uniprocessor environment, so I think it's > unnecessary to lock code with spinlock, or, better, it's redundant. That's not true since the preempt patch went in. Preempt is equivalent to SMP. > Now, I've a problem only with the use of INIT_LIST_HEAD. > I've modified the code this way. > > 1. void mtpmc_set_mm_not_writable(struct mm_struct *mm) > 2. { > 3. struct vm_area_struct *vm; > 4. struct mtpmc_wrprotected_pages *wr_page, *temp_page_wr; > 5. struct mtpmc_vm_wrprotected *temp_vma_wr; > 6. struct page *page; > 7. pte_t *pte; > 8. unsigned long addr; > 9. int initial_page; > 10. > 11. down_write(&mm->mmap_sem); > 12. for (vm = mm->mmap; vm!=NULL; vm=vm->vm_next) > 13. if(mtpmc_vm_to_save(mm, vm) == 1){ > 14. temp_vma_wr = mtpmc_mk_vm_wrprotected(vm); > 15. list_add_tail(&temp_vma_wr->list, &vm_write_protected); > 16. initial_page = 1; > 17. for(addr=vm->vm_start;addr<vm->vm_end;addr+=PAGE_SIZE){ > 18. pte = mtpmc_get_pte_from_address(mm, addr); > 19. if (pte) > 20. if (pte_write(*pte)){ > 21. set_pte(pte, pte_wrprotect(*pte)); > 22. if (initial_page == 1){ > 23. temp_vma_wr->pages = mtpmc_mk_page_wrprotected(addr); > 24. INIT_LIST_HEAD(&(temp_vma_wr->pages)->list); > 25. list_add_tail(&(temp_vma_wr->pages)->list, > &(temp_vma_wr->pages)->list); > 26. initial_page = 0; > 27. } > 28. else > 29. list_add_tail(&mtpmc_mk_page_wrprotected(addr)->list, > &(temp_vma_wr->pages)->list); > 30. } > 31. } > 32. } > 33. up_write(&mm->mmap_sem); > 34. > 35. return; > 36. } > > The problem I encountered is in initialization of pages' list. > Line regarding this problem are the ones from 22. to 30. > This lines are executed after having saved the informations of the vma that > I'm going to scan in the vm_write_protected list. > After this, I've to store information regarding the infos of pages included in > this vma. To do this, I've to create a new list containing the pages > information. > So, in line 22, I check (initial ==1) if the list for the pages of this vma > is not just created. If so, I create it (line 24) and add to it the first > element of this list (line 25). > if test is false (initial == 0), then I simply add the new page to the list. That sounds wrong to me. You should always INIT_LIST_HEAD when you allocate the structure it is in and then you should simply add the elements. Oh, I don't see your structure definitions here, but the rule of thumb is, that you *NEVER* ever have pointers to list_head in structures. You should have list_head members. That is, your temp_vma_wr->pages->list is supposed to be of type 'struct list_head' -- NOT pointer -- and the call to INIT_LIST_HEAD is supposed to be INIT_LIST_HEAD(&(temp_vma_wr->pages->list)) (or maybe pages.list, but the & must apply to the whole argument in any case). Say you have: struct something { list_head list; list_head children; some values; } struct otherthing { list_head list; other values; } DECLARE_LIST_HEAD(somethings); And then you do: struct something *alloc_something(...) { struct something *it = kmem_cache_alloc(something_cache, GFP_KERNEL); /* First let's initialize the list of children */ INIT_LIST_HEAD(&(it->children)); /* NOTE THE PARENTHESIS */ /* Other initialization */ /* And last, put it to the list */ list_add(&(it->list), &somethings); return it; } struct otherthing *alloc_otherthing(struct something *st, ...) { struct otherthing *it = kmem_cache_alloc(otherthing_cache, GFP_KERNEL); /* Some initialization */ /* And last, put it to the list */ list_add(&(it->list), &(st->children)); return it; } Note, that the parenthesis after & are superfluous in all the cases. I could have written INIT_LIST_HEAD(&it->children), list_add(&it->list, &somethings) etc, but I have put them in for clarity. > Now, the problem is that, when I scans the list, the first element of the > pages' lists is not present. In other word, the insertion of the first > element is not correct. > Can you help me on finding the problem? There's another way to organize this > dynamic list? > Thanks. > Vincenzo Mallozzi > > > > > > ___________________________________ > Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB > http://mail.yahoo.it > ------------------------------------------------------------------------------- Jan 'Bulb' Hudec <bulb@xxxxxx>
Attachment:
signature.asc
Description: Digital signature