[BACK]Return to xen_bus_dma.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / xen / x86

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/xen/x86/xen_bus_dma.c between version 1.6 and 1.7

version 1.6, 2006/01/15 22:09:52 version 1.7, 2006/08/28 19:58:57
Line 75  _xen_alloc_contig(bus_size_t size, bus_s
Line 75  _xen_alloc_contig(bus_size_t size, bus_s
         unsigned long npagesreq, npages, mfn;          unsigned long npagesreq, npages, mfn;
         bus_addr_t pa;          bus_addr_t pa;
         struct vm_page *pg, *pgnext;          struct vm_page *pg, *pgnext;
         struct pglist freelist;  
         int s, error;          int s, error;
 #ifdef XEN3  #ifdef XEN3
         struct xen_memory_reservation res;          struct xen_memory_reservation res;
 #endif  #endif
   
         TAILQ_INIT(&freelist);  
   
         /*          /*
          * When requesting a contigous memory region, the hypervisor will           * When requesting a contigous memory region, the hypervisor will
          * return a memory range aligned on size. This will automagically           * return a memory range aligned on size. This will automagically
Line 114  _xen_alloc_contig(bus_size_t size, bus_s
Line 111  _xen_alloc_contig(bus_size_t size, bus_s
                     < 0) {                      < 0) {
                         printf("xen_alloc_contig: XENMEM_decrease_reservation "                          printf("xen_alloc_contig: XENMEM_decrease_reservation "
                             "failed!\n");                              "failed!\n");
                         return ENOMEM;                          xpmap_phys_to_machine_mapping[
                               (pa - XPMAP_OFFSET) >> PAGE_SHIFT] = mfn;
   
                           error = ENOMEM;
                           goto failed;
                 }                  }
 #else  #else
                 if (HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation,                  if (HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation,
                     &mfn, 1, 0) != 1) {                      &mfn, 1, 0) != 1) {
                         printf("xen_alloc_contig: MEMOP_decrease_reservation "                          printf("xen_alloc_contig: MEMOP_decrease_reservation "
                             "failed!\n");                              "failed!\n");
                         return ENOMEM;                          xpmap_phys_to_machine_mapping[
                               (pa - XPMAP_OFFSET) >> PAGE_SHIFT] = mfn;
                           error = ENOMEM;
                           goto failed;
                 }                  }
 #endif  #endif
         }          }
Line 135  _xen_alloc_contig(bus_size_t size, bus_s
Line 139  _xen_alloc_contig(bus_size_t size, bus_s
         if (HYPERVISOR_memory_op(XENMEM_increase_reservation, &res) < 0) {          if (HYPERVISOR_memory_op(XENMEM_increase_reservation, &res) < 0) {
                 printf("xen_alloc_contig: XENMEM_increase_reservation "                  printf("xen_alloc_contig: XENMEM_increase_reservation "
                     "failed!\n");                      "failed!\n");
                 return ENOMEM;                  error = ENOMEM;
                   pg = NULL;
                   goto failed;
         }          }
 #else  #else
         if (HYPERVISOR_dom_mem_op(MEMOP_increase_reservation,          if (HYPERVISOR_dom_mem_op(MEMOP_increase_reservation,
             &mfn, 1, order) != 1) {              &mfn, 1, order) != 1) {
                 printf("xen_alloc_contig: MEMOP_increase_reservation "                  printf("xen_alloc_contig: MEMOP_increase_reservation "
                     "failed!\n");                      "failed!\n");
                 return ENOMEM;                  error = ENOMEM;
                   pg = NULL;
                   goto failed;
         }          }
 #endif  #endif
         s = splvm();          s = splvm();
Line 165  _xen_alloc_contig(bus_size_t size, bus_s
Line 173  _xen_alloc_contig(bus_size_t size, bus_s
         xpq_flush_queue();          xpq_flush_queue();
         splx(s);          splx(s);
         return 0;          return 0;
   
   failed:
           /*
            * Attempt to recover from a failed decrease or increase reservation:
            * if decrease_reservation failed, we don't have given all pages
            * back to Xen; give them back to UVM, and get the missing pages
            * from Xen.
            * if increase_reservation failed, we expect pg to be NULL and we just
            * get back the missing pages from Xen one by one.
            */
           /* give back remaining pages to UVM */
           for (; pg != NULL; pg = pgnext) {
                   pgnext = pg->pageq.tqe_next;
                   TAILQ_REMOVE(mlistp, pg, pageq);
                   uvm_pagefree(pg);
           }
           /* remplace the pages that we already gave to Xen */
           s = splvm();
           for (pg = mlistp->tqh_first; pg != NULL; pg = pgnext) {
                   pgnext = pg->pageq.tqe_next;
   #ifdef XEN3
                   res.extent_start = &mfn;
                   res.nr_extents = 1;
                   res.extent_order = 0;
                   res.address_bits = 31;
                   res.domid = DOMID_SELF;
                   if (HYPERVISOR_memory_op(XENMEM_increase_reservation, &res)
                       < 0) {
                           printf("xen_alloc_contig: recovery "
                               "XENMEM_increase_reservation failed!\n");
                           break;
                   }
   #else
                   if (HYPERVISOR_dom_mem_op(MEMOP_increase_reservation,
                       &mfn, 1, 0) != 1) {
                           printf("xen_alloc_contig: recovery "
                               "MEMOP_increase_reservation failed!\n");
                           break;
                   }
   #endif
                   pa = VM_PAGE_TO_PHYS(pg);
                   xpmap_phys_to_machine_mapping[
                       (pa - XPMAP_OFFSET) >> PAGE_SHIFT] = mfn;
                   xpq_queue_machphys_update((mfn) << PAGE_SHIFT, pa);
                   TAILQ_REMOVE(mlistp, pg, pageq);
                   uvm_pagefree(pg);
           }
           /* Flush updates through and flush the TLB */
           xpq_queue_tlb_flush();
           xpq_flush_queue();
           splx(s);
           return error;
 }  }
   
   
Line 178  _xen_bus_dmamem_alloc_range(bus_dma_tag_
Line 238  _xen_bus_dmamem_alloc_range(bus_dma_tag_
     bus_size_t alignment, bus_size_t boundary, bus_dma_segment_t *segs,      bus_size_t alignment, bus_size_t boundary, bus_dma_segment_t *segs,
     int nsegs, int *rsegs, int flags, bus_addr_t low, bus_addr_t high)      int nsegs, int *rsegs, int flags, bus_addr_t low, bus_addr_t high)
 {  {
         paddr_t curaddr, lastaddr;          bus_addr_t curaddr, lastaddr;
         bus_addr_t bus_curaddr, bus_lastaddr;  
         struct vm_page *m;          struct vm_page *m;
         struct pglist mlist;          struct pglist mlist;
         int curseg, error;          int curseg, error;
Line 210  again:
Line 269  again:
          */           */
         m = mlist.tqh_first;          m = mlist.tqh_first;
         curseg = 0;          curseg = 0;
         lastaddr = segs[curseg].ds_addr = VM_PAGE_TO_PHYS(m);          lastaddr = segs[curseg].ds_addr = _BUS_VM_PAGE_TO_BUS(m);
         segs[curseg].ds_len = PAGE_SIZE;          segs[curseg].ds_len = PAGE_SIZE;
         m = m->pageq.tqe_next;          m = m->pageq.tqe_next;
         if ((_BUS_PHYS_TO_BUS(segs[curseg].ds_addr) & (alignment - 1)) != 0)          if ((segs[curseg].ds_addr & (alignment - 1)) != 0)
                 goto dorealloc;                  goto dorealloc;
   
         for (; m != NULL; m = m->pageq.tqe_next) {          for (; m != NULL; m = m->pageq.tqe_next) {
                 curaddr = VM_PAGE_TO_PHYS(m);                  curaddr = _BUS_VM_PAGE_TO_BUS(m);
                 bus_curaddr = _BUS_PHYS_TO_BUS(curaddr);                  if ((lastaddr < low || lastaddr >= high) ||
                 bus_lastaddr = _BUS_PHYS_TO_BUS(lastaddr);                      (curaddr < low || curaddr >= high)) {
                 if ((bus_lastaddr < low || bus_lastaddr >= high) ||  
                     (bus_curaddr < low || bus_curaddr >= high)) {  
                         /*                          /*
                          * If machine addresses are outside the allowed                           * If machine addresses are outside the allowed
                          * range we have to bail. Xen2 doesn't offer an                           * range we have to bail. Xen2 doesn't offer an
Line 233  again:
Line 290  again:
                         uvm_pglistfree(&mlist);                          uvm_pglistfree(&mlist);
                         return EINVAL;                          return EINVAL;
                 }                  }
                 if (bus_curaddr == (bus_lastaddr + PAGE_SIZE)) {                  if (curaddr == (lastaddr + PAGE_SIZE)) {
                         segs[curseg].ds_len += PAGE_SIZE;                          segs[curseg].ds_len += PAGE_SIZE;
                         if ((bus_lastaddr & boundary) !=                          if ((lastaddr & boundary) !=
                             (bus_curaddr & boundary))                              (curaddr & boundary))
                                 goto dorealloc;                                  goto dorealloc;
                 }                  } else {
                 else {  
                         curseg++;                          curseg++;
                         if (curseg >= nsegs ||                          if (curseg >= nsegs ||
                             (bus_curaddr & (alignment - 1)) != 0) {                              (curaddr & (alignment - 1)) != 0) {
 dorealloc:  dorealloc:
                                 if (doingrealloc == 1)                                  if (doingrealloc == 1)
                                         panic("_xen_bus_dmamem_alloc_range: "                                          panic("_xen_bus_dmamem_alloc_range: "

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

CVSweb <webmaster@jp.NetBSD.org>