Re: Potential re(4) / netbsd-4 / i386 problem?

2010-10-28 Thread Brad du Plessis

Hi,


I've been seeing panics on a netbsd-4/i386 machine which appears to be
related to the reception of oversized frames:

re0: discarding oversize frame (len=8813) 


I've narrowed down the problem here to a specific change.
Basically with netbsd-4 branch I see the failure, but if I revert
only the file:

./src/sys/dev/mii/rgephy.c

to netbsd-4-0-1-RELEASE the problem goes away. Looking at the difference
between the 2 revisions I would guess the most likely cause is the
difference in register writes in rgephy_reset?

Unfortunately for my purposes one of the two motherboard types I have
exhibiting the problem has an RTL8111C which (without the netbsd-4 changes)
fails to detect the media automatically (forcing it to 1000baseT has it 
sync

at 100baseTX for some reason).


Are there any changes I could make to the netbsd-4 rgephy.c to find a
fix for this?(netbsd-5 has the same problem by the way)

Thanks,
 Brad


# cd /usr/src/sys/dev/mii
# cvs diff -u -r netbsd-4-0-1-RELEASE -r netbsd-4 rgephy.c

Index: rgephy.c
===
RCS file: /cvsroot/src/sys/dev/mii/rgephy.c,v
retrieving revision 1.15
retrieving revision 1.15.2.1
diff -u -r1.15 -r1.15.2.1
--- rgephy.c29 Nov 2006 13:57:59 -1.15
+++ rgephy.c18 Aug 2009 09:46:50 -1.15.2.1
@@ -1,4 +1,4 @@
-/*$NetBSD: rgephy.c,v 1.15 2006/11/29 13:57:59 tsutsui Exp $*/
+/*$NetBSD: rgephy.c,v 1.15.2.1 2009/08/18 09:46:50 bouyer Exp $*/

 /*
  * Copyright (c) 2003
@@ -33,7 +33,7 @@
  */

 #include 
-__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.15 2006/11/29 13:57:59 tsutsui 
Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.15.2.1 2009/08/18 09:46:50 
bouyer Exp $");



 /*
@@ -61,7 +61,12 @@
 static intrgephy_match(struct device *, struct cfdata *, void *);
 static voidrgephy_attach(struct device *, struct device *, void *);

-CFATTACH_DECL(rgephy, sizeof(struct mii_softc),
+struct rgephy_softc {
+struct mii_softc mii_sc;
+int mii_revision;
+};
+
+CFATTACH_DECL(rgephy, sizeof(struct rgephy_softc),
 rgephy_match, rgephy_attach, mii_phy_detach, mii_phy_activate);


@@ -72,8 +77,6 @@
 static voidrgephy_loop(struct mii_softc *);
 static voidrgephy_load_dspcode(struct mii_softc *);

-static intrgephy_mii_model;
-
 static const struct mii_phy_funcs rgephy_funcs = {
 rgephy_service, rgephy_status, rgephy_reset,
 };
@@ -103,19 +106,26 @@
 static void
 rgephy_attach(struct device *parent, struct device *self, void *aux)
 {
-struct mii_softc *sc = device_private(self);
+struct rgephy_softc *rsc = device_private(self);
+struct mii_softc *sc = &rsc->mii_sc;
 struct mii_attach_args *ma = aux;
 struct mii_data *mii = ma->mii_data;
 const struct mii_phydesc *mpd;
 int rev;
 const char *sep = "";

+rsc = device_private(self);
+sc = &rsc->mii_sc;
+ma = aux;
+mii = ma->mii_data;
+
 rev = MII_REV(ma->mii_id2);
 mpd = mii_phy_match(ma, rgephys);
 aprint_naive(": Media interface\n");
 aprint_normal(": %s, rev. %d\n", mpd->mpd_name, rev);

-sc->mii_mpd_model = rev;/* XXX miivar.h comment vs usage? */
+rsc->mii_revision = rev;
+
 sc->mii_inst = mii->mii_instance;
 sc->mii_phy = ma->mii_phyno;
 sc->mii_pdata = mii;
@@ -124,23 +134,14 @@

 sc->mii_funcs = &rgephy_funcs;

-/* Don't do isolate on this PHY. */
-sc->mii_flags |= MIIF_NOISOLATE;
-
 #defineADD(m, c)ifmedia_add(&mii->mii_media, (m), (c), NULL)
 #definePRINT(n)aprint_normal("%s%s", sep, (n)); sep = ", "

-#if 0
-ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
-BMCR_ISO);
-#endif
 #ifdef __FreeBSD__
 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
 BMCR_LOOP|BMCR_S100);
 #endif

-rgephy_mii_model = MII_MODEL(ma->mii_id2);
-
 sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
 sc->mii_capabilities &= ~BMSR_ANEG;

@@ -149,19 +150,11 @@
  * media explicitly. Why?
  */
 aprint_normal("%s: ", sc->mii_dev.dv_xname);
-#ifdef __FreeBSD__
-mii_phy_add_media(sc);
-ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst),
-RGEPHY_BMCR_FDX);
-PRINT(", 1000baseTX");
-ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), 0);
-PRINT("1000baseTX-FDX");
-#else
 if (sc->mii_capabilities & BMSR_EXTSTAT) {
 sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
 }
 mii_phy_add_media(sc);
-#endif
+
 /* rtl8169S does not report auto-sense; add manually.  */
 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), MII_NMEDIA);
 sep =", ";
@@ -177,9 +170,12 @@
 static int
 rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
 {
+struct rgephy_softc *rsc;
 struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
 int reg, speed, gig, anar;

+rsc = (struct rgephy_softc *)sc;
+
 switch (cmd) {
 case MII_POLLSTAT:
 /*
@@ -254,7 +25

Re: xmd(4) (Re: XIP)

2010-10-28 Thread YAMAMOTO Takashi
hi,

> On Thu, Oct 28, 2010 at 05:31:45AM +, YAMAMOTO Takashi wrote:
>> hi,
>> 
>> > Here's the reason why I've written xmd_machdep.c:
>> > 
>> > xmd(4) is a read-only RAM-based disk driver capable of XIP.  The
>> > main purpose is to test XIP functionality.  xmd(4) can be implemented
>> > on any platforms that supports VM in theory.  xmd(4) may be also
>> > useful for other cases where md(4) is used, but users want to save
>> > memory.  md(4) allocates memory for its storage, and copies pages
>> > from or to page cache.
>> > 
>> > xmd(4) allocates a static, read-only array and provides it as a
>> > backing store.  When it's used as XIP, it registers the array as
>> > a physical device page segment.  From VM's POV, the registered
>> > region is seen like a ROM in a device connected over some buses.
>> > 
>> > The procedure to register an array as a physical segment is somewhat
>> > strange.  The registered array resides in kernel's read-only data
>> > section.  Kernel already maps its static region (text, rodata,
>> > data, bss, ...) at boot time.  xmd(4) "re-defines" part of it as
>> > a physical device segment, like a ROM connected via another bus.
>> > 
>> > As far as the backing store array resides in main memory, you'll
>> > end up with some way to convert kernel VA back to physical address.
>> > There is no alternative to achieve the goal in MI way, or xmd.c is
>> > sprinkled like mem.c.
>> 
>> why can't you use pmap_extract?
> 
> Because looking up a paddr_t doesn't help alone.
> 
> The driver needs to allocate a physical segment object (struct
> vm_physseg) and per-page objects (struct vm_page), so that its
> region can be mapped to user address.  This is done by calling
> bus_space_physload_device() or xmd_machdep_physload(), which in
> turn call uvm_page_physload_device().
> 
> This is what happens during a fault onto xmd:
> 
> - User opens a cdev (/dev/XXX), then calls mmap() with its fd
> - User touch a mapped address
> - Fault is triggered, fault handler looks up user's map and map
>   entry
> - uvm_fault() -> udv_fault() -> cdev_mmap() -> xmd_mmap()
> - xmd_mmap() returns a "paddr_t"
> - udv_fault() enters the paddr_t to pmap_enter()
> - pmap_enter looks up a vm_physseg from a paddr_t
> - pmap_enter looks up a vm_page from a vm_physseg
> - pmap_enter looks up a vm_page_md from a vm_page
> :
> 
> This is redundant.  The problem is we use "paddr_t" as a cookie
> to identify a page in a segment, overriding its original meaning,
> physical address.  What pmap_enter needs is an ID.  Looking up a
> physical address from an ID is easy.  The reverse is not.
> 
> After these observations, I have concluded that any appearance of
> "paddr_t" in any MI code (sys/uvm, sys/kern, sys/dev) is a wrong
> approach.  I don't see how pmap_extract() helps this situation?

because you seem saying that there is no MI way to
"convert kernel VA back to physical address", i suggested 
pmap_extract.  i guess i don't understand your situation. :-)

YAMAMOTO Takashi

> 
> Masao
> 
>> 
>> YAMAMOTO Takashi
>> 
>> > 
>> > Masao
> 
> -- 
> Masao Uebayashi / Tombi Inc. / Tel: +81-90-9141-4635


Re: xmd(4) (Re: XIP)

2010-10-28 Thread Masao Uebayashi
On Thu, Oct 28, 2010 at 05:31:45AM +, YAMAMOTO Takashi wrote:
> hi,
> 
> > Here's the reason why I've written xmd_machdep.c:
> > 
> > xmd(4) is a read-only RAM-based disk driver capable of XIP.  The
> > main purpose is to test XIP functionality.  xmd(4) can be implemented
> > on any platforms that supports VM in theory.  xmd(4) may be also
> > useful for other cases where md(4) is used, but users want to save
> > memory.  md(4) allocates memory for its storage, and copies pages
> > from or to page cache.
> > 
> > xmd(4) allocates a static, read-only array and provides it as a
> > backing store.  When it's used as XIP, it registers the array as
> > a physical device page segment.  From VM's POV, the registered
> > region is seen like a ROM in a device connected over some buses.
> > 
> > The procedure to register an array as a physical segment is somewhat
> > strange.  The registered array resides in kernel's read-only data
> > section.  Kernel already maps its static region (text, rodata,
> > data, bss, ...) at boot time.  xmd(4) "re-defines" part of it as
> > a physical device segment, like a ROM connected via another bus.
> > 
> > As far as the backing store array resides in main memory, you'll
> > end up with some way to convert kernel VA back to physical address.
> > There is no alternative to achieve the goal in MI way, or xmd.c is
> > sprinkled like mem.c.
> 
> why can't you use pmap_extract?

Because looking up a paddr_t doesn't help alone.

The driver needs to allocate a physical segment object (struct
vm_physseg) and per-page objects (struct vm_page), so that its
region can be mapped to user address.  This is done by calling
bus_space_physload_device() or xmd_machdep_physload(), which in
turn call uvm_page_physload_device().

This is what happens during a fault onto xmd:

- User opens a cdev (/dev/XXX), then calls mmap() with its fd
- User touch a mapped address
- Fault is triggered, fault handler looks up user's map and map
  entry
- uvm_fault() -> udv_fault() -> cdev_mmap() -> xmd_mmap()
- xmd_mmap() returns a "paddr_t"
- udv_fault() enters the paddr_t to pmap_enter()
- pmap_enter looks up a vm_physseg from a paddr_t
- pmap_enter looks up a vm_page from a vm_physseg
- pmap_enter looks up a vm_page_md from a vm_page
:

This is redundant.  The problem is we use "paddr_t" as a cookie
to identify a page in a segment, overriding its original meaning,
physical address.  What pmap_enter needs is an ID.  Looking up a
physical address from an ID is easy.  The reverse is not.

After these observations, I have concluded that any appearance of
"paddr_t" in any MI code (sys/uvm, sys/kern, sys/dev) is a wrong
approach.  I don't see how pmap_extract() helps this situation?

Masao

> 
> YAMAMOTO Takashi
> 
> > 
> > Masao

-- 
Masao Uebayashi / Tombi Inc. / Tel: +81-90-9141-4635