Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107544007
D29969.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D29969.diff
View Options
diff --git a/sys/net/route/fib_algo.c b/sys/net/route/fib_algo.c
--- a/sys/net/route/fib_algo.c
+++ b/sys/net/route/fib_algo.c
@@ -1538,6 +1538,12 @@
set_algo_inet6_sysctl_handler, "A", "Set IPv6 lookup algo");
#endif
+static struct nhop_object *
+dummy_lookup(void *algo_data, const struct flm_lookup_key key, uint32_t scopeid)
+{
+ return (NULL);
+}
+
static void
destroy_fdh_epoch(epoch_context_t ctx)
{
@@ -1556,8 +1562,15 @@
sz = sizeof(struct fib_dp_header);
sz += sizeof(struct fib_dp) * num_tables;
fdh = malloc(sz, M_RTABLE, (waitok ? M_WAITOK : M_NOWAIT) | M_ZERO);
- if (fdh != NULL)
+ if (fdh != NULL) {
fdh->fdh_num_tables = num_tables;
+ /*
+ * Set dummy lookup function ptr always returning NULL, so
+ * we can delay algo init.
+ */
+ for (uint32_t i = 0; i < num_tables; i++)
+ fdh->fdh_idx[i].f = dummy_lookup;
+ }
return (fdh);
}
@@ -1933,19 +1946,18 @@
* Called when new route table is created.
* Selects, allocates and attaches fib algo for the table.
*/
-int
-fib_select_algo_initial(struct rib_head *rh)
+static bool
+fib_select_algo_initial(struct rib_head *rh, struct fib_dp *dp)
{
struct fib_lookup_module *flm;
struct fib_data *fd = NULL;
enum flm_op_result result;
struct epoch_tracker et;
- int error = 0;
flm = fib_check_best_algo(rh, NULL);
if (flm == NULL) {
RH_PRINTF(LOG_CRIT, rh, "no algo selected");
- return (ENOENT);
+ return (false);
}
RH_PRINTF(LOG_INFO, rh, "selected algo %s", flm->flm_name);
@@ -1956,29 +1968,58 @@
NET_EPOCH_EXIT(et);
RH_PRINTF(LOG_DEBUG, rh, "result=%d fd=%p", result, fd);
- if (result == FLM_SUCCESS) {
-
- /*
- * Attach datapath directly to avoid multiple reallocations
- * during fib growth
- */
- struct fib_dp_header *fdp;
- struct fib_dp **pdp;
-
- pdp = get_family_dp_ptr(rh->rib_family);
- if (pdp != NULL) {
- fdp = get_fib_dp_header(*pdp);
- fdp->fdh_idx[fd->fd_fibnum] = fd->fd_dp;
- FD_PRINTF(LOG_INFO, fd, "datapath attached");
- }
- } else {
- error = EINVAL;
+ if (result == FLM_SUCCESS)
+ *dp = fd->fd_dp;
+ else
RH_PRINTF(LOG_CRIT, rh, "unable to setup algo %s", flm->flm_name);
- }
fib_unref_algo(flm);
- return (error);
+ return (result == FLM_SUCCESS);
+}
+
+/*
+ * Sets up fib algo instances for the non-initialized RIBs in the @family.
+ * Allocates temporary datapath index to amortize datapaint index updates
+ * with large @num_tables.
+ */
+void
+fib_setup_family(int family, uint32_t num_tables)
+{
+ struct fib_dp_header *new_fdh = alloc_fib_dp_array(num_tables, false);
+ if (new_fdh == NULL) {
+ ALGO_PRINTF(LOG_CRIT, "Unable to setup framework for %s", print_family(family));
+ return;
+ }
+
+ for (int i = 0; i < num_tables; i++) {
+ struct rib_head *rh = rt_tables_get_rnh(i, family);
+ if (rh->rib_algo_init)
+ continue;
+ if (!fib_select_algo_initial(rh, &new_fdh->fdh_idx[i]))
+ continue;
+
+ rh->rib_algo_init = true;
+ }
+
+ FIB_MOD_LOCK();
+ struct fib_dp **pdp = get_family_dp_ptr(family);
+ struct fib_dp_header *old_fdh = get_fib_dp_header(*pdp);
+
+ /* Update the items not touched by the new init, from the old data pointer */
+ for (int i = 0; i < num_tables; i++) {
+ if (new_fdh->fdh_idx[i].f == dummy_lookup)
+ new_fdh->fdh_idx[i] = old_fdh->fdh_idx[i];
+ }
+
+ /* Ensure all index writes have completed */
+ atomic_thread_fence_rel();
+ /* Set new datapath pointer */
+ *pdp = &new_fdh->fdh_idx[0];
+
+ FIB_MOD_UNLOCK();
+
+ fib_epoch_call(destroy_fdh_epoch, &old_fdh->fdh_epoch_ctx);
}
/*
diff --git a/sys/net/route/route_tables.c b/sys/net/route/route_tables.c
--- a/sys/net/route/route_tables.c
+++ b/sys/net/route/route_tables.c
@@ -214,13 +214,6 @@
if (rh == NULL)
log(LOG_ERR, "unable to create routing table for %d.%d\n",
dom->dom_family, i);
-#ifdef FIB_ALGO
- if (fib_select_algo_initial(rh) != 0) {
- log(LOG_ERR, "unable to select algo for table %d.%d\n",
- dom->dom_family, i);
- // TODO: detach table
- }
-#endif
*prnh = rh;
}
}
@@ -238,9 +231,17 @@
atomic_thread_fence_rel();
epoch_wait_preempt(net_epoch_preempt);
- /* Finally, set number of fibs to a new value */
+ /* Set number of fibs to a new value */
V_rt_numfibs = num_tables;
+#ifdef FIB_ALGO
+ /* Attach fib algo to the new rtables */
+ for (dom = domains; dom; dom = dom->dom_next) {
+ if (dom->dom_rtattach != NULL)
+ fib_setup_family(dom->dom_family, num_tables);
+ }
+#endif
+
if (old_rt_tables != NULL)
free(old_rt_tables, M_RTABLE);
}
diff --git a/sys/net/route/route_var.h b/sys/net/route/route_var.h
--- a/sys/net/route/route_var.h
+++ b/sys/net/route/route_var.h
@@ -74,6 +74,7 @@
rt_gen_t rnh_gen_rib; /* fib algo: rib generation counter */
uint32_t rib_dying:1; /* rib is detaching */
uint32_t rib_algo_fixed:1;/* fixed algorithm */
+ uint32_t rib_algo_init:1;/* algo init done */
struct nh_control *nh_control; /* nexthop subsystem data */
CK_STAILQ_HEAD(, rib_subscription) rnh_subscribers;/* notification subscribers */
};
@@ -326,7 +327,7 @@
/* lookup_framework.c */
void fib_grow_rtables(uint32_t new_num_tables);
-int fib_select_algo_initial(struct rib_head *rh);
+void fib_setup_family(int family, uint32_t num_tables);
void fib_destroy_rib(struct rib_head *rh);
void vnet_fib_init(void);
void vnet_fib_destroy(void);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 16, 4:23 PM (21 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15818217
Default Alt Text
D29969.diff (5 KB)
Attached To
Mode
D29969: [fib algo] Delay algo init during fib growth phase to allow to reliably use rib KPI
Attached
Detach File
Event Timeline
Log In to Comment