Stop pinning modules indefinitely upon FLB registration. Instead, dynamically take a module reference when the FLB is actively used in a session (e.g., during preserve and retrieve) and release it when the session concludes. This allows modules providing FLB operations to be cleanly unloaded when not in active use by the live update orchestrator.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -115,10 +115,15 @@ static int luo_flb_file_preserve_one(struct liveupdate_flb *flb) · 114 unmodified lines | |||
| 115 | struct liveupdate_flb_op_args args = {0}; | 115 | struct liveupdate_flb_op_args args = {0}; |
| 116 | int err; | 116 | int err; |
| 117 | 117 | ||
| 118 | if (!try_module_get(flb->ops->owner)) | ||
| 119 | return -ENODEV; | ||
| 120 | |||
| 118 | args.flb = flb; | 121 | args.flb = flb; |
| 119 | err = flb->ops->preserve(&args); | 122 | err = flb->ops->preserve(&args); |
| 120 | if (err) | 123 | if (err) { |
| 124 | module_put(flb->ops->owner); | ||
| 121 | return err; | 125 | return err; |
| 126 | } | ||
| 122 | private->outgoing.data = args.data; | 127 | private->outgoing.data = args.data; |
| 123 | private->outgoing.obj = args.obj; | 128 | private->outgoing.obj = args.obj; |
| 124 | } | 129 | } |
| @@ -146,6 +151,7 @@ static void luo_flb_file_unpreserve_one(struct liveupdate_flb *flb) · 21 unmodified lines | |||
| 146 | 151 | ||
| 147 | private->outgoing.data = 0; | 152 | private->outgoing.data = 0; |
| 148 | private->outgoing.obj = NULL; | 153 | private->outgoing.obj = NULL; |
| 154 | module_put(flb->ops->owner); | ||
| 149 | } | 155 | } |
| 150 | } | 156 | } |
| 151 | } | 157 | } |
| @@ -181,12 +187,17 @@ static int luo_flb_retrieve_one(struct liveupdate_flb *flb) · 29 unmodified lines | |||
| 181 | if (!found) | 187 | if (!found) |
| 182 | return -ENOENT; | 188 | return -ENOENT; |
| 183 | 189 | ||
| 190 | if (!try_module_get(flb->ops->owner)) | ||
| 191 | return -ENODEV; | ||
| 192 | |||
| 184 | args.flb = flb; | 193 | args.flb = flb; |
| 185 | args.data = private->incoming.data; | 194 | args.data = private->incoming.data; |
| 186 | 195 | ||
| 187 | err = flb->ops->retrieve(&args); | 196 | err = flb->ops->retrieve(&args); |
| 188 | if (err) | 197 | if (err) { |
| 198 | module_put(flb->ops->owner); | ||
| 189 | return err; | 199 | return err; |
| 200 | } | ||
| 190 | 201 | ||
| 191 | private->incoming.obj = args.obj; | 202 | private->incoming.obj = args.obj; |
| 192 | private->incoming.retrieved = true; | 203 | private->incoming.retrieved = true; |
| @@ -220,6 +231,7 @@ static void luo_flb_file_finish_one(struct liveupdate_flb *flb) · 27 unmodified lines | |||
| 220 | private->incoming.data = 0; | 231 | private->incoming.data = 0; |
| 221 | private->incoming.obj = NULL; | 232 | private->incoming.obj = NULL; |
| 222 | private->incoming.finished = true; | 233 | private->incoming.finished = true; |
| 234 | module_put(flb->ops->owner); | ||
| 223 | } | 235 | } |
| 224 | } | 236 | } |
| 225 | } | 237 | } |
| @@ -395,11 +407,6 @@ int liveupdate_register_flb(struct liveupdate_file_handler *fh, · 169 unmodified lines | |||
| 395 | goto err_resume; | 407 | goto err_resume; |
| 396 | } | 408 | } |
| 397 | 409 | ||
| 398 | if (!try_module_get(flb->ops->owner)) { | ||
| 399 | err = -EAGAIN; | ||
| 400 | goto err_resume; | ||
| 401 | } | ||
| 402 | |||
| 403 | list_add_tail(&private->list, &luo_flb_global.list); | 410 | list_add_tail(&private->list, &luo_flb_global.list); |
| 404 | luo_flb_global.count++; | 411 | luo_flb_global.count++; |
| 405 | } | 412 | } |
| @@ -476,12 +483,11 @@ int liveupdate_unregister_flb(struct liveupdate_file_handler *fh, · 70 unmodified lines | |||
| 476 | private->users--; | 483 | private->users--; |
| 477 | /* | 484 | /* |
| 478 | * If this is the last file-handler with which we are registred, remove | 485 | * If this is the last file-handler with which we are registred, remove |
| 479 | * from the global list, and relese module reference. | 486 | * from the global list. |
| 480 | */ | 487 | */ |
| 481 | if (!private->users) { | 488 | if (!private->users) { |
| 482 | list_del_init(&private->list); | 489 | list_del_init(&private->list); |
| 483 | luo_flb_global.count--; | 490 | luo_flb_global.count--; |
| 484 | module_put(flb->ops->owner); | ||
| 485 | } | 491 | } |
| 486 | 492 | ||
| 487 | up_write(&luo_register_rwlock); | 493 | up_write(&luo_register_rwlock); |
| @@ -510,7 +516,8 @@ err_resume: · 22 unmodified lines | |||
| 510 | * | 516 | * |
| 511 | * Return: 0 on success, or a negative errno on failure. -ENODATA means no | 517 | * Return: 0 on success, or a negative errno on failure. -ENODATA means no |
| 512 | * incoming FLB data, -ENOENT means specific flb not found in the incoming | 518 | * incoming FLB data, -ENOENT means specific flb not found in the incoming |
| 513 | * data, and -EOPNOTSUPP when live update is disabled or not configured. | 519 | * data, -ENODEV if the FLB's module is unloading, and -EOPNOTSUPP when |
| 520 | * live update is disabled or not configured. | ||
| 514 | */ | 521 | */ |
| 515 | int liveupdate_flb_get_incoming(struct liveupdate_flb *flb, void **objp) | 522 | int liveupdate_flb_get_incoming(struct liveupdate_flb *flb, void **objp) |
| 516 | { | 523 | { |