[Lguest] [PATCH 1/1] Least Recently Used pgdirs
Jason Yeh
jasonyeh0908 at gmail.com
Wed Aug 15 13:24:25 EST 2007
Glauber de Oliveira Costa wrote:
>>
>> The patch is made against Linus git tree. If there's a need to make the
>> patch agains the lguest mercurial server, please let me know.
>>
>>
> First of all, your mailer seems to be wrapping lines, and changing
> tabs to spaces. Try to avoid it.
I would like to thank both you and Rusty's comments and apology for the
inconveniences caused by my email client. I will use external editor to
send out patches in the future. As you can probably tell, I am rather
new on sending out patches.
> It would be really interesting to see measures on that. From my POV,
> any complexity added to lguest must really pay off. Otherwise, we keep
> it simple.
I will do some benchmarking and see if the added complexity has any
benefits after making suggested changes.
>> @@ -357,7 +361,7 @@ static void flush_user_mappings(struct lguest *lg,
>> int idx)
>> unsigned int i;
>> /* Release every pgd entry up to the kernel's address. */
>> for (i = 0; i < vaddr_to_pgd_index(lg->page_offset); i++)
>> - release_pgd(lg, lg->pgdirs[idx].pgdir + i);
>> + release_pgd(lg, lg->pgdir_cur->pgdir + i); }
>
> It does not seem right. flush_user_mappings() not always release the
> mappings for the current pgdir.
As far as I can see, the only case flush_user_mappings() not releasing
the current pgdir is in new_pgdir(), but the index is assigned to the
current one after it returns. I will make it flexible for future
purposes though.
>> /* We keep several page tables. This is a simple routine to find the page
>> * table (if any) corresponding to this top-level address the Guest has
>> given
>> * us. */
>> -static unsigned int find_pgdir(struct lguest *lg, unsigned long pgtable)
>> +static struct pgdir * find_pgdir_from_list(struct lguest *lg, unsigned
>> long pgtable)
>> {
>> - unsigned int i;
>> - for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++)
>> - if (lg->pgdirs[i].cr3 == pgtable)
>> + struct pgdir *p, *rpgdir = NULL;
>> + + list_for_each_entry(p, &lg->pgdir_list, list) {
>> + if (p->cr3 == pgtable) {
>> + rpgdir = p;
>> + list_move(&rpgdir->list, &lg->pgdir_list);
> I am not sure about lguest32, but as for lguest64, there are
> situations in which finding a pgdir does not mean we're going to use
> it. So it would maybe be better to have a separate function to move
> things, once it is found. Brian Boitano (aka rusty) is the
> authoritative person for this.
I think that's the case in lguest32. I will dig into the lguest64
patches and see what's the difference. I will do what Rusty suggested
and see if moving makes any differences on performance.
>> + /* Check if we reach the maximum number of pgdirs we can hold.
>> + * Reuse the Least Recently Used one if we have. */
>> + if (lg->pgdir_list_size > PGDIR_MAX) {
>> + newpgdir= list_entry(lg->pgdir_list.prev, struct pgdir, list);
>> + list_move(&newpgdir->list, &lg->pgdir_list);
>> + } else {
>> + /* If it's never been allocated at all before, try now. */
>> + newpgdir = kmalloc(sizeof(struct pgdir), GFP_KERNEL);
> kzalloc is probably better.
>
>> + newpgdir = kmalloc(sizeof(struct pgdir), GFP_KERNEL);
> again, kzalloc is probably better here.
>
>> + if (!newpgdir) {
>> return -ENOMEM;
>> + }
>> +
>> + lg->pgdir_cur = newpgdir;
>> + newpgdir->cr3 = pgtable;
>> + newpgdir->pgdir = (spgd_t*)get_zeroed_page(GFP_KERNEL);
>> + if (!newpgdir->pgdir)
>> + return -ENOMEM;
> And what about your earlier allocation of newpgdir? Will it be here
> forever? free it before returning.
Good catch! I missed it.
Jason
More information about the Lguest
mailing list