Changeset 94b5368 in rtems-libbsd


Ignore:
Timestamp:
Jul 2, 2018, 6:21:37 AM (11 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
5cb01f277962d3127d364bf871f799b34e6b6be6, cc60cbeef68291b54f73c2d26fe3da4b837a8e06
Children:
6fb003f
Parents:
e6f6b5e
git-author:
Sebastian Huber <sebastian.huber@…> (07/02/18 06:21:37)
git-committer:
Sebastian Huber <sebastian.huber@…> (07/04/18 05:20:37)
Message:

Avoid malloc() in getsockaddr()

The getsockaddr() function is used to allocate a struct sockaddr of the
right length and initialize it with userspace provided data. It is used
for the connect(), bind() and sendit() family functions. In particular,
the sendit() function is used by the UDP send functions. This means
each UDP send needs a malloc() and free() invocation. This is a
performance problem in RTEMS (first-fit heap) and may lead to heap
fragmentation. Replace the malloc() allocation with a stack allocation.
This requires SOCK_MAXADDRLEN (= 255) of additional stack space for
libbsd.

A further optimization would be to get rid of the stack copy of the
socket address. However, this would require to check each consumer of
the address to ensure that it is not modified.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • freebsd/sys/kern/uipc_syscalls.c

    re6f6b5e r94b5368  
    8888static int getpeername1(struct thread *td, struct getpeername_args *uap,
    8989                        int compat);
     90#else /* __rtems__ */
     91struct getsockaddr_sockaddr {
     92        struct sockaddr header;
     93        char            data[SOCK_MAXADDRLEN - sizeof(struct sockaddr)];
     94};
     95
     96static int getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len);
    9097#endif /* __rtems__ */
    9198static int sockargs(struct mbuf **, char *, socklen_t, int);
     
    257264        struct sockaddr *sa;
    258265        int error;
     266#ifdef __rtems__
     267        struct getsockaddr_sockaddr gsa;
     268        sa = &gsa.header;
     269#endif /* __rtems__ */
    259270
    260271        error = getsockaddr(&sa, uap->name, uap->namelen);
    261272        if (error == 0) {
    262273                error = kern_bindat(td, AT_FDCWD, uap->s, sa);
     274#ifndef __rtems__
    263275                free(sa, M_SONAME);
     276#endif /* __rtems__ */
    264277        }
    265278        return (error);
     
    328341        struct sockaddr *sa;
    329342        int error;
     343#ifdef __rtems__
     344        struct getsockaddr_sockaddr gsa;
     345        sa = &gsa.header;
     346#endif /* __rtems__ */
    330347
    331348        error = getsockaddr(&sa, uap->name, uap->namelen);
    332349        if (error == 0) {
    333350                error = kern_bindat(td, uap->fd, uap->s, sa);
     351#ifndef __rtems__
    334352                free(sa, M_SONAME);
     353#endif /* __rtems__ */
    335354        }
    336355        return (error);
     
    675694        struct sockaddr *sa;
    676695        int error;
     696#ifdef __rtems__
     697        struct getsockaddr_sockaddr gsa;
     698        sa = &gsa.header;
     699#endif /* __rtems__ */
    677700
    678701        error = getsockaddr(&sa, uap->name, uap->namelen);
    679702        if (error == 0) {
    680703                error = kern_connectat(td, AT_FDCWD, uap->s, sa);
     704#ifndef __rtems__
    681705                free(sa, M_SONAME);
     706#endif /* __rtems__ */
    682707        }
    683708        return (error);
     
    774799        struct sockaddr *sa;
    775800        int error;
     801#ifdef __rtems__
     802        struct getsockaddr_sockaddr gsa;
     803        sa = &gsa.header;
     804#endif /* __rtems__ */
    776805
    777806        error = getsockaddr(&sa, uap->name, uap->namelen);
    778807        if (error == 0) {
    779808                error = kern_connectat(td, uap->fd, uap->s, sa);
     809#ifndef __rtems__
    780810                free(sa, M_SONAME);
     811#endif /* __rtems__ */
    781812        }
    782813        return (error);
     
    931962        struct sockaddr *to;
    932963        int error;
     964#ifdef __rtems__
     965        struct getsockaddr_sockaddr gto;
     966        to = &gto.header;
     967#endif /* __rtems__ */
    933968
    934969#ifdef CAPABILITY_MODE
     
    9791014
    9801015bad:
     1016#ifndef __rtems__
    9811017        free(to, M_SONAME);
     1018#endif /* __rtems__ */
    9821019        return (error);
    9831020}
     
    21122149{
    21132150        struct sockaddr *sa;
    2114         int error;
     2151#ifndef __rtems__
     2152        int error;
     2153#endif /* __rtems__ */
    21152154
    21162155        if (len > SOCK_MAXADDRLEN)
     
    21182157        if (len < offsetof(struct sockaddr, sa_data[0]))
    21192158                return (EINVAL);
     2159#ifndef __rtems__
    21202160        sa = malloc(len, M_SONAME, M_WAITOK);
    21212161        error = copyin(uaddr, sa, len);
     
    21312171        }
    21322172        return (error);
    2133 }
     2173#else /* __rtems__ */
     2174        sa = memcpy(*namp, uaddr, len);
     2175        sa->sa_len = len;
     2176        return (0);
     2177#endif /* __rtems__ */
     2178}
  • freebsd/sys/sys/socketvar.h

    re6f6b5e r94b5368  
    343343 * From uipc_socket and friends
    344344 */
     345#ifndef __rtems__
    345346int     getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len);
     347#endif /* __rtems__ */
    346348int     getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
    347349            struct file **fpp, u_int *fflagp, struct filecaps *havecaps);
  • rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h

    re6f6b5e r94b5368  
    11791179#define GetProxyPort _bsd_GetProxyPort
    11801180#define get_random_bytes _bsd_get_random_bytes
    1181 #define getsockaddr _bsd_getsockaddr
    11821181#define GetStateIn _bsd_GetStateIn
    11831182#define GetStateOut _bsd_GetStateOut
Note: See TracChangeset for help on using the changeset viewer.