question about dev/md/md.c out of swap?

Alfred Perlstein alfred at freebsd.org
Wed Apr 22 00:50:31 UTC 2009


Hello, a developer here at work asked me to go over 
some of the swapper code with him.

We came across something we both couldn't understand,
so I was wondering if anyone had looked at this.

in dev/md/md.c mdstart_swap() there is the following code,
it seems that in the case of VM_PAGER_ERROR most of the state
is unwound, however the page is not freed.  Is this a bug or
are we missing something?  How is the page released?


        rv = VM_PAGER_OK;                                                       
        VM_OBJECT_LOCK(sc->object);                                             
        vm_object_pip_add(sc->object, 1);                                       
        for (i = bp->bio_offset / PAGE_SIZE; i <= lastp; i++) {                 
                len = ((i == lastp) ? lastend : PAGE_SIZE) - offs;              
                                                                                
                m = vm_page_grab(sc->object, i,                                 
                    VM_ALLOC_NORMAL|VM_ALLOC_RETRY);                            
                VM_OBJECT_UNLOCK(sc->object);                                   
                sched_pin();                                                    
                sf = sf_buf_alloc(m, SFB_CPUPRIVATE);                           
                VM_OBJECT_LOCK(sc->object);                                     
                if (bp->bio_cmd == BIO_READ) {                                  
                        if (m->valid != VM_PAGE_BITS_ALL)                       
                                rv = vm_pager_get_pages(sc->object, &m, 1, 0);  
                        if (rv == VM_PAGER_ERROR) {                             
                                sf_buf_free(sf);                                
                                sched_unpin();                                  
                                vm_page_lock_queues();                          
                                vm_page_wakeup(m);                              
                                vm_page_unlock_queues();                        
                                break;                                          
                        }                                                       
                        bcopy((void *)(sf_buf_kva(sf) + offs), p, len);                         } else if (bp->bio_cmd == BIO_WRITE) {                          
                        if (len != PAGE_SIZE && m->valid != VM_PAGE_BITS_ALL)   
                                rv = vm_pager_get_pages(sc->object, &m, 1, 0);  
                        if (rv == VM_PAGER_ERROR) {                             
                                sf_buf_free(sf);                                
                                sched_unpin();                                  
                                vm_page_lock_queues();                          
                                vm_page_wakeup(m);                              
                                vm_page_unlock_queues();                        
                                break;                                          
                        }                                                       

-- 
- Alfred Perlstein


More information about the freebsd-hackers mailing list