bufq massage

2010-08-29 Thread David Gwynne
this diff is largely a mechanical change.

firstly, it makes struct bufq a member of the softc for devices
that use it, rather than it being a pointer to something that needs
to be allocated at attach. since all these devices need a bufq to
operate, it makes sense to have it allocated as part of the softc
and get bufq_init to just initialise all its fields. it also gets
rid of the possibility that you wont be able to allocate teh bufq
struct during attach, which is something you dont want to happen.

secondly, it consistently implements a split between wrapper functions
and the per discipline implementation of the bufq handlers. it
consistently does the locking in the wrappers rather than doing
half in the wrappers and the other half in the implementations.

it also consistently handles the outstanding bufq bq pointer in the
wrappers.

this hides most of the implementation inside kern_bufq.c. the only
stuff left in buf.h is for the bits each implementation needs to
put bufs on their queues.

ive tested this extensively on sd(4) and thib has tested this on
wd(4). we'd like some wider exposure, especially over suspends and
resumes on a variety of machines. i have tried to preserve the
locking semantics, but testing would be lovely.

ok?

dlg

Index: dev/ata/wd.c
===
RCS file: /cvs/src/sys/dev/ata/wd.c,v
retrieving revision 1.85
diff -u -p -r1.85 wd.c
--- dev/ata/wd.c28 Jun 2010 08:35:46 -  1.85
+++ dev/ata/wd.c25 Aug 2010 12:05:33 -
@@ -121,7 +121,7 @@ struct wd_softc {
/* General disk infos */
struct device sc_dev;
struct disk sc_dk;
-   struct bufq *sc_bufq;
+   struct bufq sc_bufq;
 
/* IDE disk soft states */
struct ata_bio sc_wdc_bio; /* current transfer */
@@ -369,7 +369,7 @@ wdattach(struct device *parent, struct d
 */
wd-sc_dk.dk_driver = wddkdriver;
wd-sc_dk.dk_name = wd-sc_dev.dv_xname;
-   wd-sc_bufq = bufq_init(BUFQ_DEFAULT);
+   bufq_init(wd-sc_bufq, BUFQ_DEFAULT);
wd-sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
if (wd-sc_sdhook == NULL)
printf(%s: WARNING: unable to establish shutdown hook\n,
@@ -413,7 +413,7 @@ wddetach(struct device *self, int flags)
 
/* Remove unprocessed buffers from queue */
s = splbio();
-   while ((bp = BUFQ_DEQUEUE(sc-sc_bufq)) != NULL) {
+   while ((bp = bufq_dequeue(sc-sc_bufq)) != NULL) {
bp-b_error = ENXIO;
bp-b_flags |= B_ERROR;
biodone(bp);
@@ -435,7 +435,7 @@ wddetach(struct device *self, int flags)
shutdownhook_disestablish(sc-sc_sdhook);
 
/* Detach disk. */
-   bufq_destroy(sc-sc_bufq);
+   bufq_destroy(sc-sc_bufq);
disk_detach(sc-sc_dk);
 
return (0);
@@ -486,7 +486,7 @@ wdstrategy(struct buf *bp)
(wd-sc_flags  (WDF_WLABEL|WDF_LABELLING)) != 0) = 0)
goto done;
/* Queue transfer on drive, activate drive and controller if idle. */
-   BUFQ_QUEUE(wd-sc_bufq, bp);
+   bufq_queue(wd-sc_bufq, bp);
s = splbio();
wdstart(wd);
splx(s);
@@ -518,7 +518,7 @@ wdstart(void *arg)
while (wd-openings  0) {
 
/* Is there a buf for us ? */
-   if ((bp = BUFQ_DEQUEUE(wd-sc_bufq)) == NULL)
+   if ((bp = bufq_dequeue(wd-sc_bufq)) == NULL)
return;
/*
 * Make the command. First lock the device
Index: kern/kern_bufq.c
===
RCS file: /cvs/src/sys/kern/kern_bufq.c,v
retrieving revision 1.14
diff -u -p -r1.14 kern_bufq.c
--- kern/kern_bufq.c19 Jul 2010 21:39:15 -  1.14
+++ kern/kern_bufq.c25 Aug 2010 12:05:33 -
@@ -30,45 +30,70 @@ SLIST_HEAD(, bufq)  bufqs = SLIST_HEAD_IN
 struct mutex   bufqs_mtx = MUTEX_INITIALIZER(IPL_NONE);
 intbufqs_stop;
 
-struct buf *(*bufq_dequeuev[BUFQ_HOWMANY])(struct bufq *, int) = {
-   bufq_disksort_dequeue,
-   bufq_fifo_dequeue
+struct bufq_impl {
+   void*(*impl_create)(void);
+   void (*impl_destroy)(void *);
+
+   void (*impl_queue)(void *, struct buf *);
+   struct buf  *(*impl_dequeue)(void *);
+   void (*impl_requeue)(void *, struct buf *);
+   int  (*impl_peek)(void *);
 };
-void (*bufq_queuev[BUFQ_HOWMANY])(struct bufq *, struct buf *) = {
+
+void   *bufq_disksort_create(void);
+voidbufq_disksort_destroy(void *);
+voidbufq_disksort_queue(void *, struct buf *);
+struct buf *bufq_disksort_dequeue(void *);
+voidbufq_disksort_requeue(void *, struct buf *);
+int bufq_disksort_peek(void *);
+
+struct bufq_impl bufq_impl_disksort = {
+   bufq_disksort_create,
+   

Re: bufq massage

2010-08-29 Thread Kenneth R Westerback
On Sun, Aug 29, 2010 at 10:26:14PM +1000, David Gwynne wrote:
 this diff is largely a mechanical change.
 
 firstly, it makes struct bufq a member of the softc for devices
 that use it, rather than it being a pointer to something that needs
 to be allocated at attach. since all these devices need a bufq to
 operate, it makes sense to have it allocated as part of the softc
 and get bufq_init to just initialise all its fields. it also gets
 rid of the possibility that you wont be able to allocate teh bufq
 struct during attach, which is something you dont want to happen.
 
 secondly, it consistently implements a split between wrapper functions
 and the per discipline implementation of the bufq handlers. it
 consistently does the locking in the wrappers rather than doing
 half in the wrappers and the other half in the implementations.
 
 it also consistently handles the outstanding bufq bq pointer in the
 wrappers.
 
 this hides most of the implementation inside kern_bufq.c. the only
 stuff left in buf.h is for the bits each implementation needs to
 put bufs on their queues.
 
 ive tested this extensively on sd(4) and thib has tested this on
 wd(4). we'd like some wider exposure, especially over suspends and
 resumes on a variety of machines. i have tried to preserve the
 locking semantics, but testing would be lovely.
 
 ok?

I like this a lot, and I will do some testing on st and cd at least as
soon as I can rebuild the appropriate box.

 Ken

 
 dlg
 
 Index: dev/ata/wd.c
 ===
 RCS file: /cvs/src/sys/dev/ata/wd.c,v
 retrieving revision 1.85
 diff -u -p -r1.85 wd.c
 --- dev/ata/wd.c  28 Jun 2010 08:35:46 -  1.85
 +++ dev/ata/wd.c  25 Aug 2010 12:05:33 -
 @@ -121,7 +121,7 @@ struct wd_softc {
   /* General disk infos */
   struct device sc_dev;
   struct disk sc_dk;
 - struct bufq *sc_bufq;
 + struct bufq sc_bufq;
  
   /* IDE disk soft states */
   struct ata_bio sc_wdc_bio; /* current transfer */
 @@ -369,7 +369,7 @@ wdattach(struct device *parent, struct d
*/
   wd-sc_dk.dk_driver = wddkdriver;
   wd-sc_dk.dk_name = wd-sc_dev.dv_xname;
 - wd-sc_bufq = bufq_init(BUFQ_DEFAULT);
 + bufq_init(wd-sc_bufq, BUFQ_DEFAULT);
   wd-sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
   if (wd-sc_sdhook == NULL)
   printf(%s: WARNING: unable to establish shutdown hook\n,
 @@ -413,7 +413,7 @@ wddetach(struct device *self, int flags)
  
   /* Remove unprocessed buffers from queue */
   s = splbio();
 - while ((bp = BUFQ_DEQUEUE(sc-sc_bufq)) != NULL) {
 + while ((bp = bufq_dequeue(sc-sc_bufq)) != NULL) {
   bp-b_error = ENXIO;
   bp-b_flags |= B_ERROR;
   biodone(bp);
 @@ -435,7 +435,7 @@ wddetach(struct device *self, int flags)
   shutdownhook_disestablish(sc-sc_sdhook);
  
   /* Detach disk. */
 - bufq_destroy(sc-sc_bufq);
 + bufq_destroy(sc-sc_bufq);
   disk_detach(sc-sc_dk);
  
   return (0);
 @@ -486,7 +486,7 @@ wdstrategy(struct buf *bp)
   (wd-sc_flags  (WDF_WLABEL|WDF_LABELLING)) != 0) = 0)
   goto done;
   /* Queue transfer on drive, activate drive and controller if idle. */
 - BUFQ_QUEUE(wd-sc_bufq, bp);
 + bufq_queue(wd-sc_bufq, bp);
   s = splbio();
   wdstart(wd);
   splx(s);
 @@ -518,7 +518,7 @@ wdstart(void *arg)
   while (wd-openings  0) {
  
   /* Is there a buf for us ? */
 - if ((bp = BUFQ_DEQUEUE(wd-sc_bufq)) == NULL)
 + if ((bp = bufq_dequeue(wd-sc_bufq)) == NULL)
   return;
   /*
* Make the command. First lock the device
 Index: kern/kern_bufq.c
 ===
 RCS file: /cvs/src/sys/kern/kern_bufq.c,v
 retrieving revision 1.14
 diff -u -p -r1.14 kern_bufq.c
 --- kern/kern_bufq.c  19 Jul 2010 21:39:15 -  1.14
 +++ kern/kern_bufq.c  25 Aug 2010 12:05:33 -
 @@ -30,45 +30,70 @@ SLIST_HEAD(, bufq)bufqs = SLIST_HEAD_IN
  struct mutex bufqs_mtx = MUTEX_INITIALIZER(IPL_NONE);
  int  bufqs_stop;
  
 -struct buf *(*bufq_dequeuev[BUFQ_HOWMANY])(struct bufq *, int) = {
 - bufq_disksort_dequeue,
 - bufq_fifo_dequeue
 +struct bufq_impl {
 + void*(*impl_create)(void);
 + void (*impl_destroy)(void *);
 +
 + void (*impl_queue)(void *, struct buf *);
 + struct buf  *(*impl_dequeue)(void *);
 + void (*impl_requeue)(void *, struct buf *);
 + int  (*impl_peek)(void *);
  };
 -void (*bufq_queuev[BUFQ_HOWMANY])(struct bufq *, struct buf *) = {
 +
 +void *bufq_disksort_create(void);
 +void  bufq_disksort_destroy(void *);
 +void  bufq_disksort_queue(void *, struct buf *);
 +struct buf   *bufq_disksort_dequeue(void *);
 +void  

He get $219,249 Last Month

2010-08-29 Thread AFANDINA
He get $219,249 Last Month

Works on ANY Computer
Profiting 112 Minutes From NOW
$4,191 In First 7 Days
$219,249 Last Month
Only 234 Copies Available - If You Don't Get Results, You'll Get A Full Refund 
AND $100 

Join Now : http://thenewsdetail.info 



Calling all pcmcia card owners

2010-08-29 Thread Theo de Raadt
Please test this diff on all pcmcia cards and machines you can find,
and report the results directly to me (ie. test the zaurus with brand
new -current code, apm i386 laptops, and the other non-suspending
cases such as amd64/i386 acpi - but don't test suspend there).

PLEASE do this very soon since I want to move ahead quickly (I am
working on making all 4 (zaurus, i386-apm, i386-acpi, amd64-acpi)
suspend-resume codepaths use the same driver infastructure; this will
remove a butload of special cases.

This will not yet make pcmcia suspend/resume correctly on many acpi
machines; that requires more diffs which will come once pcmcia is
fixed.  That's a hint to test this on the other machines soon.  There
are also some usb changes coming, and then zaurus changes, and then
i386 changes fully using the new infrastructure.. and finally, removal
of all the powerhook code.

I know there are many bugs left in here; there were many here to start
with.  This diff will be split up when it is commited, but it is better
to have it all for testing.

A rough summary of the changes:

- pcmcia was converting suspend/resume into activate/deactivate to the
  card drivers. this is WRONG, since the needs of activate and deactivate
  are different.  I have started trying to resolve this in some drivers,
  and want to get this diff in with a few fixed drivers, so that the others
  can catch up to the new better way of doing this

- some drivers do the pcmcia_function_enable() and interrupt establishment
  in their xxattach, then do it again in xxactivate.  I am trying to work
  around this now, but not yet happy with the solution

- related to the previous comment, a massive amount of #ifdef notyet
  code in these drivers will be deleted later on, but I wanted to keep
  this simple for now.

- i found a few more drivers which need a workq for resume
- to interlock against the ioctl, kettenis wants us to move the
  tsleep(sc-wi_flags thing to a rw_lock; someone has to do that work
  in some other drivers first then I will copy that here.
- there are other drivers in other subsystems which use workq and need
  the interlocks too.  is anyone going to help?

- pcmcia com continue talking serial in cu after an unsuspend

- i have been playing with looping ifconfig's and ping's through suspends
- ne works
- wi works
- malo is causing memory corruption on a re-insert and re-dhclient.  I
  cannot spot the bug.

- wdc controllers work fine; no more wdc timeout errors!
- wdc at install time requires that softraid be disabled because
  softraid is walking alldevs searching for disks and then calling a
  bucketload of functions which sleep.  It is a massive bug in softraid.

- sm, xe, an, ray are untested, but I will attempt to write diffs for
  them if someone shows up with hardware

Index: pci/if_wi_pci.c
===
RCS file: /cvs/src/sys/dev/pci/if_wi_pci.c,v
retrieving revision 1.46
diff -u -p -u -r1.46 if_wi_pci.c
--- pci/if_wi_pci.c 27 Aug 2010 18:29:44 -  1.46
+++ pci/if_wi_pci.c 29 Aug 2010 18:06:17 -
@@ -187,7 +187,18 @@ wi_pci_resume(void *arg1, void *arg2)
 {
struct wi_softc *sc = (struct wi_softc *)arg1;
 
+   int s;
+
+   s = splnet();
+   while (sc-wi_flags  WI_FLAGS_BUSY)
+   tsleep(sc-wi_flags, 0, wipwr, 0);
+   sc-wi_flags |= WI_FLAGS_BUSY;
+
wi_init(sc);
+
+   sc-wi_flags = ~WI_FLAGS_BUSY;
+   wakeup(sc-wi_flags);
+   splx(s);
 }
 
 void
Index: ic/if_wi.c
===
RCS file: /cvs/src/sys/dev/ic/if_wi.c,v
retrieving revision 1.148
diff -u -p -u -r1.148 if_wi.c
--- ic/if_wi.c  2 Jul 2010 02:40:15 -   1.148
+++ ic/if_wi.c  29 Aug 2010 18:24:33 -
@@ -1544,28 +1544,36 @@ STATIC int
 wi_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 {
int s, error = 0, i, j, len;
-   struct wi_softc *sc;
-   struct ifreq*ifr;
+   struct wi_softc *sc = ifp-if_softc;
+   struct ifreq*ifr = (struct ifreq *)data;
struct proc *p = curproc;
struct ifaddr   *ifa = (struct ifaddr *)data;
struct wi_scan_res  *res;
struct wi_scan_p2_hdr   *p2;
struct wi_req   *wreq = NULL;
u_int32_t   flags;
-
struct ieee80211_nwid   *nwidp = NULL;
struct ieee80211_nodereq_all*na;
struct ieee80211_bssid  *bssid;
 
s = splnet();
-
-   sc = ifp-if_softc;
-   ifr = (struct ifreq *)data;
-
if (!(sc-wi_flags  WI_FLAGS_ATTACHED)) {
+   error = ENODEV;
+   goto fail;
+   }
+
+   /*
+* Prevent processes from entering this function while another
+* process is tsleep'ing in it.
+*/
+   while ((sc-wi_flags  WI_FLAGS_BUSY)  error == 0)
+   error = tsleep(sc-wi_flags, 

Re: Backout mclgeti for vr(4).

2010-08-29 Thread David Gwynne
unless someone fixes mclgeti in this driver in the next 24 hours, this should
go in.

this has my ok on august 31.

On 28/08/2010, at 4:07 AM, Thordur I Bjornsson wrote:

 As seen on misc@, and also by myself sometime ago, but I forgot about
 it as work got hectic and I was moving.

 Anyways, vr(4) will not even surivie a few ping -f's, before the pools
 become corrupt, this has (obviously) something todo with how MCLGETI
 takes and puts buf's of the rings;

 Reverting MCLGETI fixes the issue. I've attached a diff, I remember
 testing it, and it survives fine.

 I did spent some time back then trying to figure this out but to no avail.
 The problem is the card is still messing with mbufs apperently after they
 have been taken of the ring (This is kind of, similar to rev1.94 I
think).

 Index: dev/pci/if_vr.c
 ===
 RCS file: /home/cvs/src/sys/dev/pci/if_vr.c,v
 retrieving revision 1.105
 diff -u -p -r1.105 if_vr.c
 --- dev/pci/if_vr.c   19 May 2010 15:27:35 -  1.105
 +++ dev/pci/if_vr.c   5 Aug 2010 15:59:05 -
 @@ -1,4 +1,4 @@
 -/*   $OpenBSD: if_vr.c,v 1.105 2010/05/19 15:27:35 oga Exp $ */
 +/*   $OpenBSD: if_vr.c,v 1.95 2009/06/04 16:56:20 sthen Exp $*/

 /*
  * Copyright (c) 1997, 1998
 @@ -135,10 +135,9 @@ void vr_setcfg(struct vr_softc *, int);
 void vr_iff(struct vr_softc *);
 void vr_reset(struct vr_softc *);
 int vr_list_rx_init(struct vr_softc *);
 -void vr_fill_rx_ring(struct vr_softc *);
 int vr_list_tx_init(struct vr_softc *);

 -int vr_alloc_mbuf(struct vr_softc *, struct vr_chain_onefrag *);
 +int vr_alloc_mbuf(struct vr_softc *, struct vr_chain_onefrag *, struct mbuf
*);

 /*
  * Supported devices  quirks
 @@ -664,7 +663,6 @@ vr_attach(struct device *parent, struct
   /*
* Call MI attach routines.
*/
 - m_clsetwms(ifp, MCLBYTES, 2, VR_RX_LIST_CNT - 1);
   if_attach(ifp);
   ether_ifattach(ifp);
   return;
 @@ -749,6 +747,9 @@ vr_list_rx_init(struct vr_softc *sc)
   sc-sc_listmap-dm_segs[0].ds_addr +
   offsetof(struct vr_list_data, vr_rx_list[i]);

 + if (vr_alloc_mbuf(sc, cd-vr_rx_chain[i], NULL))
 + return (ENOBUFS);
 +
   if (i == (VR_RX_LIST_CNT - 1))
   nexti = 0;
   else
 @@ -760,30 +761,11 @@ vr_list_rx_init(struct vr_softc *sc)
   offsetof(struct vr_list_data, vr_rx_list[nexti]));
   }

 - cd-vr_rx_prod = cd-vr_rx_cons = cd-vr_rx_chain[0];
 - cd-vr_rx_cnt = 0;
 - vr_fill_rx_ring(sc);
 + cd-vr_rx_head = cd-vr_rx_chain[0];

   return (0);
 }

 -void
 -vr_fill_rx_ring(struct vr_softc *sc)
 -{
 - struct vr_chain_data*cd;
 - struct vr_list_data *ld;
 -
 - cd = sc-vr_cdata;
 - ld = sc-vr_ldata;
 -
 - while (cd-vr_rx_cnt  VR_RX_LIST_CNT) {
 - if (vr_alloc_mbuf(sc, cd-vr_rx_prod))
 - break;
 - cd-vr_rx_prod = cd-vr_rx_prod-vr_nextdesc;
 - cd-vr_rx_cnt++;
 - }
 -}
 -
 /*
  * A frame has been uploaded: pass the resulting mbuf chain up to
  * the higher level protocols.
 @@ -791,7 +773,7 @@ vr_fill_rx_ring(struct vr_softc *sc)
 void
 vr_rxeof(struct vr_softc *sc)
 {
 - struct mbuf *m;
 + struct mbuf *m0, *m;
   struct ifnet*ifp;
   struct vr_chain_onefrag *cur_rx;
   int total_len = 0;
 @@ -799,21 +781,20 @@ vr_rxeof(struct vr_softc *sc)

   ifp = sc-arpcom.ac_if;

 - while(sc-vr_cdata.vr_rx_cnt  0) {
 + for (;;) {
 +
   bus_dmamap_sync(sc-sc_dmat, sc-sc_listmap,
   0, sc-sc_listmap-dm_mapsize,
   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 - rxstat = letoh32(sc-vr_cdata.vr_rx_cons-vr_ptr-vr_status);
 + rxstat = letoh32(sc-vr_cdata.vr_rx_head-vr_ptr-vr_status);
   if (rxstat  VR_RXSTAT_OWN)
   break;

 - rxctl = letoh32(sc-vr_cdata.vr_rx_cons-vr_ptr-vr_ctl);
 + rxctl = letoh32(sc-vr_cdata.vr_rx_head-vr_ptr-vr_ctl);

 - cur_rx = sc-vr_cdata.vr_rx_cons;
 - m = cur_rx-vr_mbuf;
 - cur_rx-vr_mbuf = NULL;
 - sc-vr_cdata.vr_rx_cons = cur_rx-vr_nextdesc;
 - sc-vr_cdata.vr_rx_cnt--;
 + m0 = NULL;
 + cur_rx = sc-vr_cdata.vr_rx_head;
 + sc-vr_cdata.vr_rx_head = cur_rx-vr_nextdesc;

   /*
* If an error occurs, update stats, clear the
 @@ -843,13 +824,24 @@ vr_rxeof(struct vr_softc *sc)
   printf(\n);
 #endif

 - m_freem(m);
 + /* Reinitialize descriptor */
 + cur_rx-vr_ptr-vr_status = htole32(VR_RXSTAT);
 + cur_rx-vr_ptr-vr_data =
 + htole32(cur_rx-vr_map-dm_segs[0].ds_addr +
 +

Re: Backout mclgeti for vr(4).

2010-08-29 Thread Theo de Raadt
 unless someone fixes mclgeti in this driver in the next 24 hours, this should
 go in.
 
 this has my ok on august 31.

It is a very nasty bug.

But we should also remember that machines with vr(4) interfaces
are pretty slow, and benefit tremendously from MCLGETI.  So it is
a crying shame to see it go.