From owner-freebsd-ia64@freebsd.org Fri Feb 26 16:27:06 2016 Return-Path: Delivered-To: freebsd-ia64@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C1BD3AB5FA4 for ; Fri, 26 Feb 2016 16:27:06 +0000 (UTC) (envelope-from wolfgang.meyer@hob.de) Received: from hobex19.hob.de (hobex29.hob.de [212.185.199.32]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 12EA417C8 for ; Fri, 26 Feb 2016 16:27:05 +0000 (UTC) (envelope-from wolfgang.meyer@hob.de) Received: from HOBEX12.hob.de (172.22.1.12) by hobex29.hob.de (172.25.1.32) with Microsoft SMTP Server (TLS) id 14.2.347.0; Fri, 26 Feb 2016 17:25:31 +0100 Received: from HOBEX11.hob.de ([fe80::b99f:1c54:7122:49b4]) by HOBEX12.hob.de ([::1]) with mapi id 14.02.0387.000; Fri, 26 Feb 2016 17:25:54 +0100 From: "Meyer, Wolfgang" To: "'freebsd-ia64@FreeBSD.org'" Subject: Running FreeBSD 10 on HP Integrity rx2800-i4 Thread-Topic: Running FreeBSD 10 on HP Integrity rx2800-i4 Thread-Index: AdFwrouHXSybdpCFRbOd/rfMC4OYsg== Date: Fri, 26 Feb 2016 16:25:53 +0000 Message-ID: Accept-Language: de-DE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [172.24.71.140] Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-BeenThere: freebsd-ia64@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Porting FreeBSD to the IA-64 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Feb 2016 16:27:06 -0000 Hello, as the release of FreeBSD 10.3 is prepared, I thought I could share some pa= tches that are necessary for running FreeBSD 10 on HP Integrity rx2800-i4 s= ervers. I'll also try to explain what the patches are trying to fix (from t= he top of my head as it has been some time since the creation of the patche= s). The original efi_md_find function assumes that the efi memory descriptors a= re sorted by physical addresses. This is not the case for the EFI of the HP= Integrity rx2800-i4 servers and hence some memory regions occupied by efi = memory descriptors are not found which leads to a boot failure (not sure if= machine check or hang). The following patch fixes this behaviour. efi.patch: --- sys/ia64/ia64/efi.c.orig 2015-07-31 14:18:37.000000000 +0200 +++ sys/ia64/ia64/efi.c 2015-08-13 16:15:53.631602000 +0200 @@ -205,21 +205,28 @@ efi_md_find(vm_paddr_t pa) { static struct efi_md *last =3D NULL; - struct efi_md *md, *p0, *p1; + struct efi_md *md, *md0; + int up =3D 0; md =3D (last !=3D NULL) ? last : efi_md_first(); - p1 =3D p0 =3D NULL; - while (md !=3D NULL && md !=3D p1) { + if (md =3D=3D NULL) { + return (NULL); + } + md0 =3D md; + up =3D (pa > md->md_phys) ? 1 : 0; + + do { if (pa >=3D md->md_phys && - pa < md->md_phys + md->md_pages * EFI_PAGE_SIZE) { + pa < md->md_phys + md->md_pages * EFI_PAGE_SIZE) { last =3D md; return (md); } - p1 =3D p0; - p0 =3D md; - md =3D (pa < md->md_phys) ? efi_md_prev(md) : efi_md_next(m= d); - } + md =3D up ? efi_md_next(md) : efi_md_prev(md); + if (md =3D=3D NULL) { + md =3D up ? efi_md_first() : efi_md_last(); + } + } while (md !=3D md0); return (NULL); } The firmware of the HP Integrity rx2800-i4 contains a myriad of small memor= y descriptors of the type EFI_MD_TYPE_BS_CODE and EFI_MD_TYPE_BS_DATA. Tryi= ng to use them f=FCr the physmem map overburdens the structures holding the= descriptors. Increasing the size of the structures doesn't help. The solut= ion is not to use them for the physmem map. Furthermore the mapping pagesiz= e shift should not be odd (as is the case for the rx2800 firmware). machdep.patch: --- sys/ia64/ia64/machdep.c.orig 2015-07-31 14:18:23.000000000 +0200 +++ sys/ia64/ia64/machdep.c 2015-08-13 15:59:29.624985000 +0200 @@ -622,6 +622,9 @@ shft++; sz >>=3D 1; } + if (shft & 1) { + shft++; + } pte =3D PTE_PRESENT | PTE_MA_WB | PTE_ACCESSED | PTE_DIRTY | PTE_PL_KERN | PTE_AR_RWX; @@ -761,11 +764,11 @@ case EFI_MD_TYPE_RECLAIM: case EFI_MD_TYPE_RT_CODE: case EFI_MD_TYPE_RT_DATA: + case EFI_MD_TYPE_BS_CODE: + case EFI_MD_TYPE_BS_DATA: /* Don't use these memory regions. */ ia64_physmem_track(md->md_phys, mdlen); break; - case EFI_MD_TYPE_BS_CODE: - case EFI_MD_TYPE_BS_DATA: case EFI_MD_TYPE_CODE: case EFI_MD_TYPE_DATA: case EFI_MD_TYPE_FREE: --- sys/ia64/ia64/dump_machdep.c.orig 2015-08-13 07:59:43.000000000 +0200 +++ sys/ia64/ia64/dump_machdep.c 2015-08-13 15:59:04.582524000 +0200 @@ -203,9 +203,7 @@ while (mdp !=3D NULL) { if (mdp->md_type =3D=3D EFI_MD_TYPE_FREE || mdp->md_type =3D=3D EFI_MD_TYPE_DATA || - mdp->md_type =3D=3D EFI_MD_TYPE_CODE || - mdp->md_type =3D=3D EFI_MD_TYPE_BS_DATA || - mdp->md_type =3D=3D EFI_MD_TYPE_BS_CODE) { + mdp->md_type =3D=3D EFI_MD_TYPE_CODE) { error =3D (*cb)(mdp, seqnr++, arg); if (error) return (-error); The igb driver has alignment issues that lead to kernel panics. Furthermore= watchdog timeouts drag the network interface down regularily and are also = causing kernel panics. The following patch fixes this. Alas the network dri= ver still has some severe issues that hampers the usage (for example remote= access via ssh). Ping rtts on the local network are on average in the orde= r of hundreds of milliseconds. On FreeBSD 9 the igb driver also needs fixin= g due to alignment issues and watchdog timeouts but there the network perfo= rmance in the end is satisfying with ping rtts in the sub-millisecond regim= e. if_igb.patch: --- sys/dev/e1000/if_igb.h.orig 2016-02-26 13:10:58.344796000 +0100 +++ sys/dev/e1000/if_igb.h 2016-02-26 13:55:00.420598000 +0100 @@ -599,6 +599,8 @@ #define IGB_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx) #define IGB_RX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rx_mtx, = MA_OWNED) +#define IGB_RXBUF_ALIGN (sizeof(uint32_t)) + #define UPDATE_VF_REG(reg, last, cur) \ { \ u32 new =3D E1000_READ_REG(hw, reg); \ --- sys/dev/e1000/if_igb.c.orig 2016-02-26 13:11:36.634944000 +0100 +++ sys/dev/e1000/if_igb.c 2016-02-26 14:19:43.271194000 +0100 @@ -171,6 +171,9 @@ static __inline void igb_rx_discard(struct rx_ring *, int); static __inline void igb_rx_input(struct rx_ring *, struct ifnet *, struct mbuf *, u32); +#ifndef __NO_STRICT_ALIGNMENT +static __inline void igb_fixup_rx(struct mbuf *); +#endif static bool igb_rxeof(struct igb_queue *, int, int *); static void igb_rx_checksum(u32, struct mbuf *, u32); @@ -3993,7 +3996,8 @@ ** would have been taken, so none processed ** for too long indicates a hang. */ - if ((!processed) && ((ticks - txr->watchdog_time) > IGB_WATCHDOG)) + if ((!processed) && ((ticks - txr->watchdog_time) > IGB_WATCHDOG) &= & + txr->queue_status =3D=3D IGB_QUEUE_WORKING) txr->queue_status |=3D IGB_QUEUE_HUNG; if (txr->tx_avail >=3D IGB_QUEUE_THRESHOLD) @@ -4051,6 +4055,9 @@ mh->m_pkthdr.len =3D mh->m_len =3D MHLEN; mh->m_len =3D MHLEN; mh->m_flags |=3D M_PKTHDR; +#ifndef __NO_STRICT_ALIGNMENT + m_adj(mh, IGB_RXBUF_ALIGN); +#endif /* Get the memory mapping */ error =3D bus_dmamap_load_mbuf_sg(rxr->htag, rxbuf->hmap, mh, hseg, &nsegs, BUS_DMA_NOWAIT); @@ -4076,6 +4083,9 @@ mp =3D rxbuf->m_pack; mp->m_pkthdr.len =3D mp->m_len =3D adapter->rx_mbuf_sz; +#ifndef __NO_STRICT_ALIGNMENT + m_adj(mp, IGB_RXBUF_ALIGN); +#endif /* Get the memory mapping */ error =3D bus_dmamap_load_mbuf_sg(rxr->ptag, rxbuf->pmap, mp, pseg, &nsegs, BUS_DMA_NOWAIT); @@ -4291,6 +4301,9 @@ mh =3D rxbuf->m_head; mh->m_len =3D mh->m_pkthdr.len =3D MHLEN; mh->m_flags |=3D M_PKTHDR; +#ifndef __NO_STRICT_ALIGNMENT + m_adj(mh, IGB_RXBUF_ALIGN); +#endif /* Get the memory mapping */ error =3D bus_dmamap_load_mbuf_sg(rxr->htag, rxbuf->hmap, rxbuf->m_head, hseg, @@ -4312,6 +4325,9 @@ } mp =3D rxbuf->m_pack; mp->m_pkthdr.len =3D mp->m_len =3D adapter->rx_mbuf_sz; +#ifndef __NO_STRICT_ALIGNMENT + m_adj(mp, IGB_RXBUF_ALIGN); +#endif /* Get the memory mapping */ error =3D bus_dmamap_load_mbuf_sg(rxr->ptag, rxbuf->pmap, mp, pseg, @@ -4747,6 +4763,23 @@ IGB_RX_LOCK(rxr); } +#ifndef __NO_STRICT_ALIGNMENT +static __inline void +igb_fixup_rx(struct mbuf *m) +{ + int i; + uint16_t *src, *dst; + + src =3D mtod(m, uint16_t *); + dst =3D src - (IGB_RXBUF_ALIGN - ETHER_ALIGN) / sizeof *src; + + for (i =3D 0; i < (m->m_len / sizeof(uint16_t) + 1); i++) + *dst++ =3D *src++; + + m->m_data -=3D IGB_RXBUF_ALIGN - ETHER_ALIGN; +} +#endif + /********************************************************************* * * This routine executes in interrupt context. It replenishes @@ -4893,6 +4926,9 @@ if (eop) { rxr->fmp->m_pkthdr.rcvif =3D ifp; +#ifndef __NO_STRICT_ALIGNMENT + igb_fixup_rx(rxr->fmp); +#endif ifp->if_ipackets++; rxr->rx_packets++; /* capture data for AIM */ Maybe these patches are of use for someone. Regards, Wolfgang Meyer ________________________________ Follow HOB: - HOB: http://www.hob.de/redirect/hob.html - Xing: http://www.hob.de/redirect/xing.html - LinkedIn: http://www.hob.de/redirect/linkedin.html - HOBLink Mobile: http://www.hob.de/redirect/hoblinkmobile.html - Facebook: http://www.hob.de/redirect/facebook.html - Twitter: http://www.hob.de/redirect/twitter.html - YouTube: http://www.hob.de/redirect/youtube.html - E-Mail: http://www.hob.de/redirect/mail.html HOB GmbH & Co. KG Schwadermuehlstr. 3 D-90556 Cadolzburg Geschaeftsfuehrung: Klaus Brandstaetter, Zoran Adamovic AG Fuerth, HRA 5180 Steuer-Nr. 218/163/00107 USt-ID-Nr. DE 132747002 Komplementaerin HOB electronic Beteiligungs GmbH AG Fuerth, HRB 3416