Index: kern/uipc_socket.c =================================================================== --- kern/uipc_socket.c (wersja 243669) +++ kern/uipc_socket.c (kopia robocza) @@ -276,6 +276,8 @@ socket_zone = uma_zcreate("socket", sizeof(struct socket), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); uma_zone_set_max(socket_zone, maxsockets); + uma_zone_set_warning(socket_zone, + "kern.ipc.maxsockets limit exceeded, please see tuning(7)."); EVENTHANDLER_REGISTER(maxsockets_change, socket_zone_change, NULL, EVENTHANDLER_PRI_FIRST); } Index: kern/uipc_usrreq.c =================================================================== --- kern/uipc_usrreq.c (wersja 243669) +++ kern/uipc_usrreq.c (kopia robocza) @@ -1778,6 +1778,8 @@ if (unp_zone == NULL) panic("unp_init"); uma_zone_set_max(unp_zone, maxsockets); + uma_zone_set_warning(unp_zone, + "kern.ipc.maxsockets limit exceeded, please see tuning(7)."); EVENTHANDLER_REGISTER(maxsockets_change, unp_zone_change, NULL, EVENTHANDLER_PRI_ANY); LIST_INIT(&unp_dhead); Index: kern/kern_mbuf.c =================================================================== --- kern/kern_mbuf.c (wersja 243669) +++ kern/kern_mbuf.c (kopia robocza) @@ -311,6 +311,8 @@ uma_zone_set_max(zone_mbuf, nmbufs); nmbufs = uma_zone_get_max(zone_mbuf); } + uma_zone_set_warning(zone_mbuf, + "kern.ipc.nmbufs limit exceeded, please see tuning(7)."); zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES, mb_ctor_clust, mb_dtor_clust, @@ -324,6 +326,8 @@ uma_zone_set_max(zone_clust, nmbclusters); nmbclusters = uma_zone_get_max(zone_clust); } + uma_zone_set_warning(zone_clust, + "kern.ipc.nmbclusters limit exceeded, please see tuning(7)."); zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack, mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf); @@ -341,6 +345,8 @@ uma_zone_set_max(zone_jumbop, nmbjumbop); nmbjumbop = uma_zone_get_max(zone_jumbop); } + uma_zone_set_warning(zone_jumbop, + "kern.ipc.nmbjumbop limit exceeded, please see tuning(7)."); zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES, mb_ctor_clust, mb_dtor_clust, @@ -355,6 +361,8 @@ uma_zone_set_max(zone_jumbo9, nmbjumbo9); nmbjumbo9 = uma_zone_get_max(zone_jumbo9); } + uma_zone_set_warning(zone_jumbo9, + "kern.ipc.nmbjumbo9 limit exceeded, please see tuning(7)."); zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES, mb_ctor_clust, mb_dtor_clust, @@ -369,6 +377,8 @@ uma_zone_set_max(zone_jumbo16, nmbjumbo16); nmbjumbo16 = uma_zone_get_max(zone_jumbo16); } + uma_zone_set_warning(zone_jumbo16, + "kern.ipc.nmbjumbo16 limit exceeded, please see tuning(7)."); zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int), NULL, NULL, Index: vm/uma_int.h =================================================================== --- vm/uma_int.h (wersja 243669) +++ vm/uma_int.h (kopia robocza) @@ -331,6 +331,11 @@ uint16_t uz_fills; /* Outstanding bucket fills */ uint16_t uz_count; /* Highest value ub_ptr can have */ + /* The next three fields are used to print a rate-limited warnings. */ + const char *uz_warning; /* Warning to print on failure */ + struct timeval uz_lastfail; /* Time of last allocation failure */ + int uz_curfail; /* Number of failures after last warning */ + /* * This HAS to be the last item because we adjust the zone size * based on NCPU and then allocate the space for the zones. Index: vm/uma.h =================================================================== --- vm/uma.h (wersja 243669) +++ vm/uma.h (kopia robocza) @@ -476,6 +476,18 @@ int uma_zone_get_max(uma_zone_t zone); /* + * Sets a warning to be printed when limit is reached + * + * Arguments: + * zone The zone we will warn about + * warning Warning content + * + * Returns: + * Nothing + */ +void uma_zone_set_warning(uma_zone_t zone, const char *warning); + +/* * Obtains the approximate current number of items allocated from a zone * * Arguments: Index: vm/uma_core.c =================================================================== --- vm/uma_core.c (wersja 243669) +++ vm/uma_core.c (kopia robocza) @@ -363,6 +363,17 @@ zone_drain(ubz->ubz_zone); } +static void +zone_log_warning(uma_zone_t zone) +{ + + if (zone->uz_warning == NULL) + return; + + if (ppsratecheck(&zone->uz_lastfail, &zone->uz_curfail, 1)) + printf("[zone: %s] %s\n", zone->uz_name, zone->uz_warning); +} + static inline uma_keg_t zone_first_keg(uma_zone_t zone) { @@ -1432,6 +1443,9 @@ zone->uz_sleeps = 0; zone->uz_fills = zone->uz_count = 0; zone->uz_flags = 0; + zone->uz_warning = NULL; + bzero(&zone->uz_lastfail, sizeof(zone->uz_lastfail)); + zone->uz_curfail = 0; keg = arg->keg; if (arg->flags & UMA_ZONE_SECONDARY) { @@ -2191,8 +2205,10 @@ * If this is not a multi-zone, set the FULL bit. * Otherwise slab_multi() takes care of it. */ - if ((zone->uz_flags & UMA_ZFLAG_MULTI) == 0) + if ((zone->uz_flags & UMA_ZFLAG_MULTI) == 0) { zone->uz_flags |= UMA_ZFLAG_FULL; + zone_log_warning(zone); + } if (flags & M_NOWAIT) break; zone->uz_sleeps++; @@ -2339,6 +2355,7 @@ if (full && !empty) { zone->uz_flags |= UMA_ZFLAG_FULL; zone->uz_sleeps++; + zone_log_warning(zone); msleep(zone, zone->uz_lock, PVM, "zonelimit", hz/100); zone->uz_flags &= ~UMA_ZFLAG_FULL; continue; @@ -2881,6 +2898,16 @@ } /* See uma.h */ +void +uma_zone_set_warning(uma_zone_t zone, const char *warning) +{ + + ZONE_LOCK(zone); + zone->uz_warning = warning; + ZONE_UNLOCK(zone); +} + +/* See uma.h */ int uma_zone_get_cur(uma_zone_t zone) {