NAS-144187 / 25.10.8 / Stop hook_setup_ha sync loop between HA controllers (by yocalebo) (by bugclerk) (#19926)
When both controllers think they are active, `hook_setup_ha` on each one
sends its database to the other and calls interface.sync there. That
runs the same hook on the other side, which calls straight back. This
happens when failover is disabled and the VIP is on the controller not
marked as master, or when both controllers hold the VIP. The loop never
ends on its own and the first push can overwrite the other controller's
newer database.
Skip the sync and log a warning when the other controller also reports
MASTER.
Original PR: https://github.com/truenas/middleware/pull/19924
Original PR: https://github.com/truenas/middleware/pull/19925
Co-authored-by: caleb <yocalebo at gmail.com>
[NFC][TSan] Remove redundant Context::report_mtx (#228605)
Context::report_mtx was only ever acquired immediately alongside
ScopedErrorReportLock (in ScopedReport and BackgroundThread). Remove
report_mtx and MutexTypeReport and rely on ScopedErrorReportLock.
Assisted-by: Gemini
NAS-144187 / 27.0.0 / Stop hook_setup_ha sync loop between HA controllers (by yocalebo) (#19925)
When both controllers think they are active, `hook_setup_ha` on each one
sends its database to the other and calls interface.sync there. That
runs the same hook on the other side, which calls straight back. This
happens when failover is disabled and the VIP is on the controller not
marked as master, or when both controllers hold the VIP. The loop never
ends on its own and the first push can overwrite the other controller's
newer database.
Skip the sync and log a warning when the other controller also reports
MASTER.
Original PR: https://github.com/truenas/middleware/pull/19924
Co-authored-by: caleb <yocalebo at gmail.com>
NAS-144105 / 27.0.0 / Log the reason when SED initial setup fails (by yocalebo) (#19923)
Every failure during SED initial setup returned a status and threw away
the error. A wrong password, a disk that dropped off the bus and a drive
that refused commands all looked the same in the log. The error is now
logged with its traceback before the status is returned. The returned
status does not change.
Original PR: https://github.com/truenas/middleware/pull/19922
Co-authored-by: caleb <yocalebo at gmail.com>
NAS-144187 / 28.0.0-BETA.1 / Stop hook_setup_ha sync loop between HA controllers (#19924)
When both controllers think they are active, `hook_setup_ha` on each one
sends its database to the other and calls interface.sync there. That
runs the same hook on the other side, which calls straight back. This
happens when failover is disabled and the VIP is on the controller not
marked as master, or when both controllers hold the VIP. The loop never
ends on its own and the first push can overwrite the other controller's
newer database.
Skip the sync and log a warning when the other controller also reports
MASTER.
math/deal.ii: unbreak by disabling the mumps option
deal.ii was built successfully when math/mumps wasn't installed.
Due to some recent rearrangements in dependencies math/mumps
is now installed and this triggered failure in deal.ii because
it expects a newer mumps.
What was done: the MUMPS option was disabled to fix build.
TODO: math/mumps, which is currently Code-Aster specific, should
be moved to math/mumps-code-aster, and math/mumps should
contain the latest version of mumps.
(cherry picked from commit 6b05b1a038e7a80612a8e5d335dbf8bc1e80e994)
math/deal.ii: unbreak by disabling the mumps option
deal.ii was built successfully when math/mumps wasn't installed.
Due to some recent rearrangements in dependencies math/mumps
is now installed and this triggered failure in deal.ii because
it expects a newer mumps.
What was done: the MUMPS option was disabled to fix build.
TODO: math/mumps, which is currently Code-Aster specific, should
be moved to math/mumps-code-aster, and math/mumps should
contain the latest version of mumps.
[flang] Add an example plugin defining compiler directives
flangDirectivesPlugin registers directives with the prefix "example" (a
callback on a procedure, a watch on a variable or COMMON block, and a note on
either). The tests check their lowering to fir.directives attributes, the
semantic and parse errors, and their round trip through module files.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[flang] Plugin directives: COMMON block arguments
/name/ names a COMMON block in a plugin directive, as subject or argument
of variable kind. It resolves to the block visible in the scope, is written
back in module files, and lowers to a reference to the block's fir.global.
Assisted-by: Claude Code (Opus 5.5)
[flang] Plugin directives: declare subjects and arguments the unit does not use
A directive is lowered onto the operation of its subject, and its procedure
and variable arguments become symbol references. Subjects that the unit does
not define or reference had no operation, so their directives were dropped,
and use-associated module variables as arguments became strings:
- The unit that holds the directive now declares its subject (a procedure,
e.g. an external one with an interface body, or a module variable, which
may be another module's), as a reference would. A unit that sees the
directive through a module file still lowers it only for what it uses.
- Procedure and module variable arguments are declared likewise.
Semantics records for each directive whether it was read from a module file;
Lower gets declareModuleVariable for a used module variable outside of any
function.
Assisted-by: Claude Code (Opus 5.5)
[flang] Plugin directives: address review comments
- Accept as procedure arguments only subprograms and external procedures:
reject dummy procedures, procedure pointers, statement functions and
intrinsics; a generic name stands for its specific procedure of the same
name, and is an error without one. Accept as variable arguments only
variables (not e.g. derived types or module names). Lowering no longer
calls mangleName on anything else, which aborted.
- Make a malformed argument list of a directive with a registered prefix a
parse error instead of an ignored, unrecognized directive.
- Leave out of a module file a directive whose arguments are not visible in
the module (e.g. an internal procedure or a dummy argument), with a
warning, instead of writing a module file that cannot be read.
- In a function without a RESULT clause, take its name as the function, not
its result variable, where a procedure may be meant.
- Record a directive on the host's symbol when its subject is host
associated (a module procedure naming itself), so it is written to the
module file.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[flang] Compiler directives defined by plugins (prototype)
Lets a plugin loaded with `flang -fc1 -load` define its own directives,
!DIR$ prefix keyword [( arg [, arg]... )], arg -> [name =] value,
value -> name | integer | character-literal
and see them, with their names resolved to symbols, in MLIR.
- Support: a registry (flang/Support/PluginDirectives.h) where a plugin
registers each directive with the kinds of its arguments (procedure,
variable, integer, string) and of its subject, from a static initializer.
- Parser: CompilerDirective::Plugin, accepted only for a registered prefix,
so other directives parse as before.
- Semantics: name arguments are resolved in the enclosing scope (procedures
under CONTAINS can be named before they are defined), checked against the
registered kinds, and recorded with their subject: a leading positional
name, or the enclosing subprogram. Errors for undeclared names, wrong
kinds, unknown keywords and missing arguments.
[9 lines not shown]
[TSan] Release locks before OutputReport on all platforms (#228554)
https://github.com/llvm/llvm-project/pull/151495 moved OutputReport
outside the lock scope (ThreadRegistryLock, slot_lock, slots_lock) on
Apple platforms only.
Holding these locks during OutputReport can also deadlock on non-Apple
platforms. For example, when halt_on_error=1, abort_on_error=1, and
handle_abort=0 are set, OutputReport calls Die() -> Abort(), which
raises SIGABRT and invokes a user signal handler via
CallUserSignalHandler with TSan instrumentation re-enabled. If the
signal handler executes enough instrumented code to overflow the
active TracePart, TraceSwitchPartImpl -> TracePartAlloc attempts to
acquire ctx->slot_mtx and self-deadlocks because slots_lock is still
held by ReportRace.
Remove the SANITIZER_APPLE conditional compilation so locks are
released before OutputReport across all platforms.
Assisted-by: Gemini
[mlir][CIR] Use OpFoldResults for the cir.scope fold
The CIR dialect now sets the `useOpFoldResults` bit. ODS then declares
`OpFoldResults fold(FoldAdaptor)` for each CIR op that does not have
exactly one fixed result. `cir.scope` is the only such op with a fold.
Its fold now returns the yielded value directly. The behavior does not
change. The existing test `clang/test/CIR/Transforms/canonicalize.cir`
covers this fold.
Signed-off-by: Víctor Pérez Carrasco <victor.pc.upm at gmail.com>
[mlir] Deprecate the legacy fold APIs with a results vector
The legacy `Operation::fold` overloads with a
`SmallVectorImpl<OpFoldResult> &` parameter drop partial folds. The
overloads that return `OpFoldResults` keep them.
This patch moves every in-tree caller of the legacy overloads to the
overloads that return `OpFoldResults`, except the unit tests of the
legacy APIs. `OpFoldResultsTest.cpp` suppresses the deprecation warnings
for these tests. Then the patch marks these APIs as deprecated: the two
legacy `Operation::fold` overloads, the legacy general `foldTrait` form,
the legacy fold hook overloads of `DynamicOpDefinition`, and the
`DynamicOpDefinition::LegacyFoldHookFn` alias. ODS cannot put an
attribute on an interface method, so only the documentation marks the
legacy `DialectFoldInterface::fold` method as deprecated.
The new code in `cir::CastOp::fold` also fixes two bugs. The fold
crashed when the source of an integral cast was a block argument, and it
read slot 0 when the source was a different result of its op. Two new
[17 lines not shown]
[mlir][memref] Use OpFoldResults for memref folds
The memref dialect now sets `useOpFoldResults`. ODS then declares
`OpFoldResults fold(FoldAdaptor)` for each memref op that does not have
exactly one fixed result. This patch moves the seven folds of such ops
to the new form: `copy`, `dealloc`, `dma_start`, `dma_wait`,
`extract_strided_metadata`, `prefetch`, and `store`. The behavior of
these folds does not change, except for `extract_strided_metadata`.
The `memref.extract_strided_metadata` fold created `arith.constant` ops
with its own builder and replaced the uses of the constant results
itself. No driver saw these changes. The fold now returns a partial
fold: one slot for each constant result, and an in-place mark when it
removes a `memref.cast` source. This patch removes the helper
`replaceConstantUsesOf`, which has no other user.
DialectConversion folds an op before it applies the patterns. So the
conversion did not see the new constants and left them unconverted.
With pattern rollback on, the conversion now does not apply the partial
[27 lines not shown]
[mlir][arith] Use OpFoldResults for arith folds
The arith dialect now sets `useOpFoldResults`. ODS then declares
`OpFoldResults fold(FoldAdaptor)` for each arith op that does not have
exactly one fixed result. This patch moves the four folds of such ops to
the new form: `addui_extended`, `subui_extended`, `mulsi_extended`, and
`mului_extended`. The behavior of these folds does not change, with two
exceptions.
The `arith.mulsi_extended` fold now replaces the low result of
`mulsi_extended(x, 1)` by `x`, and keeps the high result. This is also
correct for i1, where the constant `true` is -1. The i1 tests in
`Arith/canonicalize.mlir` change their expected output.
In a graph region, the identity fold of `addui_extended`,
`subui_extended`, or `mului_extended` can forward an operand that is the
other result of the same op. The fold also replaces that result, so the
new form drops the fold. The legacy form gave a correct result in this
case, because it first moved the uses to the forwarded result, and then
[7 lines not shown]
[mlir][linalg] Use OpFoldResults for linalg folds
The linalg dialect now sets the `useOpFoldResults` bit. ODS then
declares `OpFoldResults fold(FoldAdaptor)` for each linalg op that does
not have exactly one fixed result. This patch moves the eleven folds of
such ops in `LinalgOps.cpp` to the new form. It also changes the fold
template of `mlir-linalg-ods-yaml-gen`, so the generated named ops use
the new form too.
The behavior of the folds does not change. A fold that returned the
result of `memref::foldMemRefCast` now returns the same in-place state
through the `LogicalResult` constructor. The folds of `transpose`,
`pack`, and `unpack` return their replacement value directly.
The yaml-gen test now checks the generated fold definition.
A build directory that uses a native `mlir-linalg-ods-yaml-gen` does
not regenerate `LinalgNamedStructuredOps.yamlgen.cpp.inc` when the tool
changes. Delete that file before the build.
[2 lines not shown]
[mlir][vector] Use OpFoldResults for vector folds
The vector dialect now sets the `useOpFoldResults` bit. ODS then
declares `OpFoldResults fold(FoldAdaptor)` for each vector op that does
not have exactly one fixed result. This patch moves the five folds of
such ops to the new form: `to_elements`, `transfer_write`, `store`,
`masked_store`, and `mask`.
The behavior of the folds does not change, except in the graph-region
case below. A fold that returned success with an empty vector now
returns `success()`, which is an in-place change. A fold that filled the
vector now returns its values.
The all-true fold of `vector.mask` moves the masked op out of the
region, and the terminator then has null operands. So this fold must
replace every result, and the driver erases the op. A mask without
results has no slot to replace, so the fold reports the move as an
in-place change.
[26 lines not shown]
[mlir][affine] Use OpFoldResults for affine folds
The affine dialect now sets `useOpFoldResults`. ODS then declares
`OpFoldResults fold(FoldAdaptor)` for each affine op that does not have
exactly one fixed result. This patch moves the eight folds of such ops
to the new form: `dma_start`, `dma_wait`, `for`, `if`, `store`,
`prefetch`, `parallel`, and `delinearize_index`. The behavior of these
folds does not change, with two exceptions.
The `affine.delinearize_index` fold now replaces each result whose basis
element is 1 with the constant 0, and keeps the other results. In
`Tensor/bubble-up-extract-slice-op.mlir`, these results now fold to a
constant 0. The new test `Affine/fold-partial.mlir` runs
`-test-single-fold` and `-sccp`, because `-canonicalize` also runs
`DropUnitExtentBasis`, which hides a broken fold.
In a graph region, an init of a zero-trip `affine.for` can be another
result of the same loop. The fold also replaces that result, so the new
form drops the fold. For a forward chain such as
[21 lines not shown]
[mlir][tblgen] Warn about the deprecated multi-result fold form
The legacy form `LogicalResult fold(FoldAdaptor,
SmallVectorImpl<OpFoldResult> &)` will be removed. This patch makes
`mlir-tblgen -gen-op-decls` warn when a dialect keeps `useOpFoldResults`
at 0 and has an op with `hasFolder` that does not have exactly one fixed
result. The warning points at the dialect definition. A note names the
first op that uses the legacy form.
The warning comes once for each dialect in one `-gen-op-decls` run. A
dialect with ops in more than one `.td` file can warn once for each file
that contains such an op. `-gen-op-defs` does not warn.
No in-tree dialect warns, because each in-tree dialect with such an op
already sets the bit.
The diagnostic follows the `-on-deprecated` option: `none` silences it,
`warn` (the default) warns, and `error` reports an error and fails the
run. `MlirTblgenMain.h` exposes the option value through
[3 lines not shown]
[mlir] Use OpFoldResults in more upstream dialects
The scf, shape, sparse_tensor, gpu, math, and builtin dialects now set
the `useOpFoldResults` bit. ODS then declares `OpFoldResults
fold(FoldAdaptor)` for each of their ops that does not have exactly one
fixed result. This patch moves the seven folds of such ops to the new
form: `scf.if`, `shape.split_at`, `sparse_tensor.crd_translate`,
`gpu.memcpy`, `gpu.memset`, `math.sincos`, and
`builtin.unrealized_conversion_cast`.
The behavior of the folds does not change, except in the graph-region
case below. Each fold builds the same normalized `OpFoldResults` object
that the legacy adapter built from the old return. The existing tests of
each dialect cover these folds.
In a graph region, an operand that `unrealized_conversion_cast` or
`sparse_tensor.crd_translate` forwards can be another result of the
same op that the same fold replaces. The new form drops such a fold.
For a forward chain, the legacy form gave a correct result by the order
[22 lines not shown]
[mlir] Use the replaced results of a partial fold in SCCP
`SparseConstantPropagation` now uses the `OpFoldResults` form of
`Operation::fold`. It merges the value of each replaced result into the
lattice of that result, and it sets each kept result to the entry
state. A kept result must not join with its own lattice, because that
leaves the lattice uninitialized. Before this patch, SCCP saw a partial
fold as a failure and set every result to the entry state.
The new test in `sccp.mlir` checks that SCCP uses the replaced results
and that the kept result stays overdefined.
Signed-off-by: Víctor Pérez Carrasco <victor.pc.upm at gmail.com>